2 * << Haru Free PDF Library >> -- hpdf_fontdef_tt.c
4 * URL: http://libharu.org
6 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
9 * Permission to use, copy, modify, distribute and sell this software
10 * and its documentation for any purpose is hereby granted without fee,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
14 * It is provided "as is" without express or implied warranty.
16 * 2006.08.24 fixed for composite glyph description.
19 #include "hpdf_conf.h"
20 #include "hpdf_utils.h"
21 #include "hpdf_fontdef.h"
24 #define HPDF_TTF_MAX_MEM_SIZ 10000
26 #define HPDF_REQUIRED_TAGS_COUNT 13
28 static const char * const REQUIRED_TAGS[HPDF_REQUIRED_TAGS_COUNT] = {
46 FreeFunc (HPDF_FontDef fontdef);
50 LoadFontData (HPDF_FontDef fontdef,
57 LoadFontData2 (HPDF_FontDef fontdef,
64 InitAttr (HPDF_FontDef fontdef);
68 GetUINT32 (HPDF_Stream stream,
73 GetUINT16 (HPDF_Stream stream,
78 GetINT16 (HPDF_Stream stream,
83 WriteUINT32 (HPDF_Stream stream,
88 WriteUINT16 (HPDF_Stream stream,
93 WriteINT16 (HPDF_Stream stream,
98 UINT32Swap (HPDF_UINT32 *value);
102 UINT16Swap (HPDF_UINT16 *value);
106 INT16Swap (HPDF_INT16 *value);
110 LoadTTFTable (HPDF_FontDef fontdef);
114 ParseHead (HPDF_FontDef fontdef);
118 ParseMaxp (HPDF_FontDef fontdef);
122 ParseHhea (HPDF_FontDef fontdef);
126 ParseCMap (HPDF_FontDef fontdef);
130 ParseCMAP_format0 (HPDF_FontDef fontdef,
135 ParseCMAP_format4 (HPDF_FontDef fontdef,
140 ParseHmtx (HPDF_FontDef fontdef);
144 ParseLoca (HPDF_FontDef fontdef);
148 LoadUnicodeName (HPDF_Stream stream,
154 ParseName (HPDF_FontDef fontdef);
158 ParseOS2 (HPDF_FontDef fontdef);
161 static HPDF_TTFTable*
162 FindTable (HPDF_FontDef fontdef,
167 CleanFunc (HPDF_FontDef fontdef);
171 CheckCompositGryph (HPDF_FontDef fontdef,
175 /*---------------------------------------------------------------------------*/
176 /*---------------------------------------------------------------------------*/
179 FreeFunc (HPDF_FontDef fontdef)
181 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
183 HPDF_PTRACE ((" HPDF_TTFontDef_FreeFunc\n"));
188 HPDF_FreeMem (fontdef->mmgr, attr);
194 CleanFunc (HPDF_FontDef fontdef)
196 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
197 HPDF_MemSet (attr->glyph_tbl.flgs, 0,
198 sizeof (HPDF_BYTE) * attr->num_glyphs);
199 attr->glyph_tbl.flgs[0] = 1;
204 InitAttr (HPDF_FontDef fontdef)
206 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
210 HPDF_FreeMem (fontdef->mmgr, attr->char_set);
213 HPDF_FreeMem (fontdef->mmgr, attr->h_metric);
215 if (attr->name_tbl.name_records)
216 HPDF_FreeMem (fontdef->mmgr, attr->name_tbl.name_records);
218 if (attr->cmap.end_count)
219 HPDF_FreeMem (fontdef->mmgr, attr->cmap.end_count);
221 if (attr->cmap.start_count)
222 HPDF_FreeMem (fontdef->mmgr, attr->cmap.start_count);
224 if (attr->cmap.id_delta)
225 HPDF_FreeMem (fontdef->mmgr, attr->cmap.id_delta);
227 if (attr->cmap.id_range_offset)
228 HPDF_FreeMem (fontdef->mmgr, attr->cmap.id_range_offset);
230 if (attr->cmap.glyph_id_array)
231 HPDF_FreeMem (fontdef->mmgr, attr->cmap.glyph_id_array);
233 if (attr->offset_tbl.table)
234 HPDF_FreeMem (fontdef->mmgr, attr->offset_tbl.table);
236 if (attr->glyph_tbl.flgs)
237 HPDF_FreeMem (fontdef->mmgr, attr->glyph_tbl.flgs);
239 if (attr->glyph_tbl.offsets)
240 HPDF_FreeMem (fontdef->mmgr, attr->glyph_tbl.offsets);
243 HPDF_Stream_Free (attr->stream);
249 HPDF_TTFontDef_New (HPDF_MMgr mmgr)
251 HPDF_FontDef fontdef;
252 HPDF_TTFontDefAttr fontdef_attr;
254 HPDF_PTRACE ((" HPDF_TTFontDef_New\n"));
259 fontdef = HPDF_GetMem (mmgr, sizeof(HPDF_FontDef_Rec));
263 HPDF_MemSet (fontdef, 0, sizeof(HPDF_FontDef_Rec));
264 fontdef->sig_bytes = HPDF_FONTDEF_SIG_BYTES;
265 fontdef->mmgr = mmgr;
266 fontdef->error = mmgr->error;
267 fontdef->type = HPDF_FONTDEF_TYPE_TRUETYPE;
268 fontdef->clean_fn = CleanFunc;
269 fontdef->free_fn = FreeFunc;
271 fontdef_attr = HPDF_GetMem (mmgr, sizeof(HPDF_TTFontDefAttr_Rec));
273 HPDF_FreeMem (fontdef->mmgr, fontdef);
277 fontdef->attr = fontdef_attr;
278 HPDF_MemSet ((HPDF_BYTE *)fontdef_attr, 0, sizeof(HPDF_TTFontDefAttr_Rec));
279 fontdef->flags = HPDF_FONT_STD_CHARSET;
286 HPDF_TTFontDef_Load (HPDF_MMgr mmgr,
291 HPDF_FontDef fontdef;
293 HPDF_PTRACE ((" HPDF_TTFontDef_Load\n"));
295 fontdef = HPDF_TTFontDef_New (mmgr);
298 HPDF_Stream_Free (stream);
302 ret = LoadFontData (fontdef, stream, embedding, 0);
303 if (ret != HPDF_OK) {
304 HPDF_FontDef_Free (fontdef);
313 HPDF_TTFontDef_Load2 (HPDF_MMgr mmgr,
319 HPDF_FontDef fontdef;
321 HPDF_PTRACE ((" HPDF_TTFontDef_Load\n"));
323 fontdef = HPDF_TTFontDef_New (mmgr);
326 HPDF_Stream_Free (stream);
330 ret = LoadFontData2 (fontdef, stream, index, embedding);
331 if (ret != HPDF_OK) {
332 HPDF_FontDef_Free (fontdef);
340 #ifdef HPDF_TTF_DEBUG
342 DumpTable (HPDF_FontDef fontdef)
344 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
348 for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
350 HPDF_TTFTable *tbl = FindTable (fontdef, REQUIRED_TAGS[i]);
353 HPDF_PTRACE ((" ERR: cannot seek %s\n", fname));
357 HPDF_MemSet (fname, 0, 9);
358 HPDF_MemCpy (fname, REQUIRED_TAGS[i], 4);
359 HPDF_MemCpy (fname + 4, ".dat", 4);
360 HPDF_PTRACE ((" %s open\n", fname));
362 if (HPDF_MemCmp(fname, "OS/2", 4) == 0)
365 stream = HPDF_FileWriter_New (fontdef->mmgr, fname);
368 HPDF_PTRACE ((" ERR: cannot open %s\n", fname));
371 HPDF_UINT tbl_len = tbl->length;
373 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
374 if (ret != HPDF_OK) {
375 HPDF_PTRACE ((" ERR: cannot seek \n"));
376 HPDF_Stream_Free (stream);
381 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
382 HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
387 HPDF_Stream_Read (attr->stream, buf, &len);
391 ret = HPDF_Stream_Write (stream, buf, len);
392 if (ret != HPDF_OK) {
393 HPDF_PTRACE ((" ERR: cannot write\n"));
402 HPDF_Stream_Free (stream);
409 LoadFontData (HPDF_FontDef fontdef,
414 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
418 HPDF_PTRACE ((" HPDF_TTFontDef_LoadFontData\n"));
420 attr->stream = stream;
421 attr->embedding = embedding;
423 if ((ret = HPDF_Stream_Seek (stream, offset, HPDF_SEEK_SET)) != HPDF_OK)
426 if ((ret = LoadTTFTable (fontdef)) != HPDF_OK)
429 #ifdef HPDF_DUMP_FONTDATA
431 #endif /* HPDF_DUMP_FONTDATA */
433 if ((ret = ParseHead (fontdef)) != HPDF_OK)
436 if ((ret = ParseMaxp (fontdef)) != HPDF_OK)
439 if ((ret = ParseHhea (fontdef)) != HPDF_OK)
442 if ((ret = ParseCMap (fontdef)) != HPDF_OK)
445 if ((ret = ParseHmtx (fontdef)) != HPDF_OK)
448 if ((ret = ParseLoca (fontdef)) != HPDF_OK)
451 if ((ret = ParseName (fontdef)) != HPDF_OK)
454 if ((ret = ParseOS2 (fontdef)) != HPDF_OK)
457 tbl = FindTable (fontdef, "glyf");
459 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 4);
461 attr->glyph_tbl.base_offset = tbl->offset;
462 fontdef->cap_height =
463 (HPDF_UINT16)HPDF_TTFontDef_GetCharBBox (fontdef, (HPDF_UINT16)'H').top;
465 (HPDF_UINT16)HPDF_TTFontDef_GetCharBBox (fontdef, (HPDF_UINT16)'x').top;
466 fontdef->missing_width = (HPDF_INT16)((HPDF_UINT32)attr->h_metric[0].advance_width * 1000 /
467 attr->header.units_per_em);
469 HPDF_PTRACE ((" fontdef->cap_height=%d\n", fontdef->cap_height));
470 HPDF_PTRACE ((" fontdef->x_height=%d\n", fontdef->x_height));
471 HPDF_PTRACE ((" fontdef->missing_width=%d\n", fontdef->missing_width));
474 HPDF_Stream_Free (attr->stream);
482 LoadFontData2 (HPDF_FontDef fontdef,
487 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
490 HPDF_UINT32 num_fonts;
494 HPDF_PTRACE ((" HPDF_TTFontDef_LoadFontData2\n"));
496 attr->stream = stream;
497 attr->embedding = embedding;
499 ret = HPDF_Stream_Seek (stream, 0, HPDF_SEEK_SET);
504 if ((ret = HPDF_Stream_Read (stream, tag, &size)) != HPDF_OK)
507 if (HPDF_MemCmp (tag, (HPDF_BYTE *)"ttcf", 4) != 0)
508 return HPDF_SetError (fontdef->error, HPDF_INVALID_TTC_FILE, 0);
510 if ((ret = HPDF_Stream_Seek (stream, 8, HPDF_SEEK_SET)) != HPDF_OK)
513 if ((ret = GetUINT32 (stream, &num_fonts)) != HPDF_OK)
516 HPDF_PTRACE((" HPDF_TTFontDef_LoadFontData2 num_fonts=%u\n",
517 (HPDF_UINT)num_fonts));
519 if (index >= num_fonts)
520 return HPDF_SetError (fontdef->error, HPDF_INVALID_TTC_INDEX, 0);
522 /* read offset table for target font and set stream positioning to offset
525 if ((ret = HPDF_Stream_Seek (stream, 12 + index * 4, HPDF_SEEK_SET)) !=
529 if ((ret = GetUINT32 (stream, &offset)) != HPDF_OK)
532 return LoadFontData (fontdef, stream, embedding, offset);
536 HPDF_TTFontDef_GetCharBBox (HPDF_FontDef fontdef,
539 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
540 HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid(fontdef, unicode);
542 HPDF_Box bbox = HPDF_ToBox(0, 0, 0, 0);
547 HPDF_PTRACE ((" GetCharHeight cannot get gid char=0x%04x\n", unicode));
551 if (attr->header.index_to_loc_format == 0)
556 ret = HPDF_Stream_Seek (attr->stream, attr->glyph_tbl.base_offset +
557 attr->glyph_tbl.offsets[gid] * m + 2, HPDF_SEEK_SET);
562 ret += GetINT16 (attr->stream, &i);
563 bbox.left = (HPDF_REAL)((HPDF_INT32)i * 1000 / attr->header.units_per_em);
565 ret += GetINT16 (attr->stream, &i);
566 bbox.bottom = (HPDF_REAL)((HPDF_INT32)i * 1000 / attr->header.units_per_em);
568 ret += GetINT16 (attr->stream, &i);
569 bbox.right = (HPDF_REAL)((HPDF_INT32)i * 1000 / attr->header.units_per_em);
571 ret += GetINT16 (attr->stream, &i);
572 bbox.top = (HPDF_REAL)((HPDF_INT32)i * 1000 / attr->header.units_per_em);
575 return HPDF_ToBox(0, 0, 0, 0);
577 HPDF_PTRACE((" PdfTTFontDef_GetCharBBox char=0x%04X, "
578 "box=[%f,%f,%f,%f]\n", unicode, bbox.left, bbox.bottom, bbox.right,
586 GetUINT32 (HPDF_Stream stream,
590 HPDF_UINT size = sizeof (HPDF_UINT32);
592 ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
593 if (ret != HPDF_OK) {
605 GetUINT16 (HPDF_Stream stream,
609 HPDF_UINT size = sizeof (HPDF_UINT16);
611 ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
612 if (ret != HPDF_OK) {
624 GetINT16 (HPDF_Stream stream,
628 HPDF_UINT size = sizeof (HPDF_INT16);
630 ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
631 if (ret != HPDF_OK) {
642 WriteUINT32 (HPDF_Stream stream,
646 HPDF_UINT32 tmp = value;
650 ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
659 WriteUINT16 (HPDF_Stream stream,
663 HPDF_UINT16 tmp = value;
667 ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
676 WriteINT16 (HPDF_Stream stream,
680 HPDF_INT16 tmp = value;
684 ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
693 LoadTTFTable (HPDF_FontDef fontdef)
695 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
696 HPDF_STATUS ret = HPDF_OK;
700 HPDF_PTRACE ((" HPDF_TTFontDef_LoadTTFTable\n"));
702 ret += GetUINT32 (attr->stream, &attr->offset_tbl.sfnt_version);
703 ret += GetUINT16 (attr->stream, &attr->offset_tbl.num_tables);
704 ret += GetUINT16 (attr->stream, &attr->offset_tbl.search_range);
705 ret += GetUINT16 (attr->stream, &attr->offset_tbl.entry_selector);
706 ret += GetUINT16 (attr->stream, &attr->offset_tbl.range_shift);
709 return HPDF_Error_GetCode (fontdef->error);
711 if (attr->offset_tbl.num_tables * sizeof(HPDF_TTFTable) >
712 HPDF_TTF_MAX_MEM_SIZ)
713 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
715 attr->offset_tbl.table = HPDF_GetMem (fontdef->mmgr,
716 sizeof(HPDF_TTFTable) * attr->offset_tbl.num_tables);
717 if (!attr->offset_tbl.table)
718 return HPDF_Error_GetCode (fontdef->error);
720 tbl = attr->offset_tbl.table;
721 for (i = 0; i < attr->offset_tbl.num_tables; i++) {
724 ret += HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)tbl->tag, &siz);
725 ret += GetUINT32 (attr->stream, &tbl->check_sum);
726 ret += GetUINT32 (attr->stream, &tbl->offset);
727 ret += GetUINT32 (attr->stream, &tbl->length);
729 HPDF_PTRACE((" [%d] tag=[%c%c%c%c] check_sum=%u offset=%u length=%u\n",
730 i, tbl->tag[0], tbl->tag[1], tbl->tag[2], tbl->tag[3],
731 (HPDF_UINT)tbl->check_sum, (HPDF_UINT)tbl->offset,
732 (HPDF_UINT)tbl->length));
735 return HPDF_Error_GetCode (fontdef->error);;
745 ParseHead (HPDF_FontDef fontdef)
747 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
748 HPDF_TTFTable *tbl = FindTable (fontdef, "head");
752 HPDF_PTRACE ((" HPDF_TTFontDef_ParseHead\n"));
755 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 5);
757 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
762 ret += HPDF_Stream_Read (attr->stream,
763 (HPDF_BYTE *)&attr->header.version_number, &siz);
764 ret += GetUINT32 (attr->stream, &attr->header.font_revision);
765 ret += GetUINT32 (attr->stream, &attr->header.check_sum_adjustment);
766 ret += GetUINT32 (attr->stream, &attr->header.magic_number);
767 ret += GetUINT16 (attr->stream, &attr->header.flags);
768 ret += GetUINT16 (attr->stream, &attr->header.units_per_em);
771 ret += HPDF_Stream_Read (attr->stream, attr->header.created, &siz);
773 ret += HPDF_Stream_Read (attr->stream, attr->header.modified, &siz);
775 ret += GetINT16 (attr->stream, &attr->header.x_min);
776 ret += GetINT16 (attr->stream, &attr->header.y_min);
777 ret += GetINT16 (attr->stream, &attr->header.x_max);
778 ret += GetINT16 (attr->stream, &attr->header.y_max);
779 ret += GetUINT16 (attr->stream, &attr->header.mac_style);
780 ret += GetUINT16 (attr->stream, &attr->header.lowest_rec_ppem);
781 ret += GetINT16 (attr->stream, &attr->header.font_direction_hint);
782 ret += GetINT16 (attr->stream, &attr->header.index_to_loc_format);
783 ret += GetINT16 (attr->stream, &attr->header.glyph_data_format);
786 return HPDF_Error_GetCode (fontdef->error);
788 fontdef->font_bbox. left = (HPDF_REAL)((HPDF_INT32)attr->header.x_min * 1000 /
789 attr->header.units_per_em);
790 fontdef->font_bbox. bottom = (HPDF_REAL)((HPDF_INT32)attr->header.y_min * 1000 /
791 attr->header.units_per_em);
792 fontdef->font_bbox. right = (HPDF_REAL)((HPDF_INT32)attr->header.x_max * 1000 /
793 attr->header.units_per_em);
794 fontdef->font_bbox. top = (HPDF_REAL)((HPDF_INT32)attr->header.y_max * 1000 /
795 attr->header.units_per_em);
802 ParseMaxp (HPDF_FontDef fontdef)
804 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
805 HPDF_TTFTable *tbl = FindTable (fontdef, "maxp");
808 HPDF_PTRACE ((" HPDF_TTFontDef_ParseMaxp\n"));
811 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 9);
813 ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 4, HPDF_SEEK_SET);
817 ret = GetUINT16 (attr->stream, &attr->num_glyphs);
819 HPDF_PTRACE((" HPDF_TTFontDef_ParseMaxp num_glyphs=%u\n",
827 ParseHhea (HPDF_FontDef fontdef)
829 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
830 HPDF_TTFTable *tbl = FindTable (fontdef, "hhea");
833 HPDF_PTRACE ((" HPDF_TTFontDef_ParseHhea\n"));
836 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 6);
838 ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 4, HPDF_SEEK_SET);
842 ret += GetINT16 (attr->stream, &fontdef->ascent);
843 fontdef->ascent = (HPDF_INT16)((HPDF_INT32)fontdef->ascent * 1000 /
844 attr->header.units_per_em);
845 ret += GetINT16 (attr->stream, &fontdef->descent);
846 fontdef->descent = (HPDF_INT16)((HPDF_INT32)fontdef->descent * 1000 /
847 attr->header.units_per_em);
850 return HPDF_Error_GetCode (fontdef->error);
852 ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 34, HPDF_SEEK_SET);
856 ret = GetUINT16 (attr->stream, &attr->num_h_metric);
858 return HPDF_Error_GetCode (fontdef->error);
860 HPDF_PTRACE((" HPDF_TTFontDef_ParseHhea num_h_metric=%u\n",
861 attr->num_h_metric));
868 ParseCMap (HPDF_FontDef fontdef)
870 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
871 HPDF_TTFTable *tbl = FindTable (fontdef, "cmap");
874 HPDF_UINT16 num_cmap;
876 HPDF_UINT32 ms_unicode_encoding_offset = 0;
877 HPDF_UINT32 byte_encoding_offset = 0;
879 HPDF_PTRACE ((" HPDF_TTFontDef_ParseCMap\n"));
882 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 1);
884 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
888 ret += GetUINT16 (attr->stream, &version);
890 return HPDF_Error_GetCode (fontdef->error);
893 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
895 ret += GetUINT16 (attr->stream, &num_cmap);
897 return HPDF_Error_GetCode (fontdef->error);
899 for (i = 0; i < num_cmap; i++) {
900 HPDF_UINT16 platformID;
901 HPDF_UINT16 encodingID;
904 HPDF_INT32 save_offset;
906 ret += GetUINT16 (attr->stream, &platformID);
907 ret += GetUINT16 (attr->stream, &encodingID);
908 ret += GetUINT32 (attr->stream, &offset);
910 return HPDF_Error_GetCode (fontdef->error);
912 save_offset = HPDF_Stream_Tell (attr->stream);
914 return HPDF_Error_GetCode (fontdef->error);
916 ret = HPDF_Stream_Seek (attr->stream, tbl->offset + offset,
921 ret = GetUINT16 (attr->stream, &format);
925 HPDF_PTRACE((" HPDF_TTFontDef_ParseCMap tables[%d] platformID=%u "
926 "encodingID=%u format=%u offset=%u\n", i, platformID,
927 encodingID, format, (HPDF_UINT)offset));
929 /* MS-Unicode-CMAP is used for priority */
930 if (platformID == 3 && encodingID == 1 && format == 4) {
931 ms_unicode_encoding_offset = offset;
935 /* Byte-Encoding-CMAP will be used if MS-Unicode-CMAP is not found */
936 if (platformID == 1 && encodingID ==0 && format == 1)
937 byte_encoding_offset = offset;
939 ret = HPDF_Stream_Seek (attr->stream, save_offset, HPDF_SEEK_SET);
944 if (ms_unicode_encoding_offset != 0) {
945 HPDF_PTRACE((" found microsoft unicode cmap.\n"));
946 ret = ParseCMAP_format4(fontdef, ms_unicode_encoding_offset +
948 } else if (byte_encoding_offset != 0) {
949 HPDF_PTRACE((" found byte encoding cmap.\n"));
950 ret = ParseCMAP_format0(fontdef, byte_encoding_offset + tbl->offset);
952 HPDF_PTRACE((" cannot found target cmap.\n"));
953 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
961 ParseCMAP_format0 (HPDF_FontDef fontdef,
964 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
966 HPDF_BYTE array[256];
971 HPDF_PTRACE((" ParseCMAP_format0\n"));
973 ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET);
977 ret += GetUINT16 (attr->stream, &attr->cmap.format);
978 ret += GetUINT16 (attr->stream, &attr->cmap.length);
979 ret += GetUINT16 (attr->stream, &attr->cmap.language);
982 return HPDF_Error_GetCode (fontdef->error);
984 if (attr->cmap.format != 0)
985 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
988 ret = HPDF_Stream_Read (attr->stream, array, &size);
992 attr->cmap.glyph_id_array_count = 256;
993 attr->cmap.glyph_id_array = HPDF_GetMem (fontdef->mmgr,
994 sizeof (HPDF_UINT16) * 256);
995 if (!attr->cmap.glyph_id_array)
996 return HPDF_Error_GetCode (fontdef->error);
998 parray = attr->cmap.glyph_id_array;
999 for (i = 0; i < 256; i++) {
1000 *parray = attr->cmap.glyph_id_array[i];
1001 HPDF_PTRACE((" ParseCMAP_format0 glyph_id_array[%d]=%u\n",
1011 ParseCMAP_format4 (HPDF_FontDef fontdef,
1014 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1017 HPDF_UINT16 *pend_count;
1018 HPDF_UINT16 *pstart_count;
1019 HPDF_INT16 *pid_delta;
1020 HPDF_UINT16 *pid_range_offset;
1021 HPDF_UINT16 *pglyph_id_array;
1022 HPDF_INT32 num_read;
1024 HPDF_PTRACE((" ParseCMAP_format4\n"));
1026 if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET)) !=
1030 ret += GetUINT16 (attr->stream, &attr->cmap.format);
1031 ret += GetUINT16 (attr->stream, &attr->cmap.length);
1032 ret += GetUINT16 (attr->stream, &attr->cmap.language);
1035 return HPDF_Error_GetCode (fontdef->error);
1037 if (attr->cmap.format != 4)
1038 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1040 ret += GetUINT16 (attr->stream, &attr->cmap.seg_count_x2);
1041 ret += GetUINT16 (attr->stream, &attr->cmap.search_range);
1042 ret += GetUINT16 (attr->stream, &attr->cmap.entry_selector);
1043 ret += GetUINT16 (attr->stream, &attr->cmap.range_shift);
1046 return HPDF_Error_GetCode (fontdef->error);
1049 attr->cmap.end_count = HPDF_GetMem (fontdef->mmgr,
1050 sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1051 if (!attr->cmap.end_count)
1052 return HPDF_Error_GetCode (fontdef->error);
1054 pend_count = attr->cmap.end_count;
1055 for (i = 0; i < (HPDF_UINT)attr->cmap.seg_count_x2 / 2; i++)
1056 if ((ret = GetUINT16 (attr->stream, pend_count++)) != HPDF_OK)
1059 if ((ret = GetUINT16 (attr->stream, &attr->cmap.reserved_pad)) != HPDF_OK)
1063 attr->cmap.start_count = HPDF_GetMem (fontdef->mmgr,
1064 sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1065 if (!attr->cmap.start_count)
1066 return HPDF_Error_GetCode (fontdef->error);
1068 pstart_count = attr->cmap.start_count;
1069 for (i = 0; i < (HPDF_UINT)attr->cmap.seg_count_x2 / 2; i++)
1070 if ((ret = GetUINT16 (attr->stream, pstart_count++)) != HPDF_OK)
1074 attr->cmap.id_delta = HPDF_GetMem (fontdef->mmgr,
1075 sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1076 if (!attr->cmap.id_delta)
1077 return HPDF_Error_GetCode (fontdef->error);
1079 pid_delta = attr->cmap.id_delta;
1080 for (i = 0; i < (HPDF_UINT)attr->cmap.seg_count_x2 / 2; i++)
1081 if ((ret = GetINT16 (attr->stream, pid_delta++)) != HPDF_OK)
1084 /* id_range_offset */
1085 attr->cmap.id_range_offset = HPDF_GetMem (fontdef->mmgr,
1086 sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1087 if (!attr->cmap.id_range_offset)
1088 return HPDF_Error_GetCode (fontdef->error);
1090 pid_range_offset = attr->cmap.id_range_offset;
1091 for (i = 0; i < (HPDF_UINT)attr->cmap.seg_count_x2 / 2; i++)
1092 if ((ret = GetUINT16 (attr->stream, pid_range_offset++)) != HPDF_OK)
1095 num_read = HPDF_Stream_Tell (attr->stream) - offset;
1097 return HPDF_Error_GetCode (fontdef->error);
1099 attr->cmap.glyph_id_array_count = (attr->cmap.length - num_read) / 2;
1101 if (attr->cmap.glyph_id_array_count > 0) {
1102 /* glyph_id_array */
1103 attr->cmap.glyph_id_array = HPDF_GetMem (fontdef->mmgr,
1104 sizeof(HPDF_UINT16) * attr->cmap.glyph_id_array_count);
1105 if (!attr->cmap.glyph_id_array)
1106 return HPDF_Error_GetCode (fontdef->error);
1108 pglyph_id_array = attr->cmap.glyph_id_array;
1109 for (i = 0; i < attr->cmap.glyph_id_array_count; i++)
1110 if ((ret = GetUINT16 (attr->stream, pglyph_id_array++)) != HPDF_OK)
1113 attr->cmap.glyph_id_array = NULL;
1115 #ifdef LIBHPDF_DEBUG
1116 /* print all elements of cmap table */
1117 for (i = 0; i < (HPDF_UINT)attr->cmap.seg_count_x2 / 2; i++) {
1118 HPDF_PTRACE((" ParseCMAP_format4[%d] start_count=0x%04X, "
1119 "end_count=0x%04X, id_delta=%d, id_range_offset=%u\n", i,
1120 attr->cmap.start_count[i], attr->cmap.end_count[i],
1121 attr->cmap.id_delta[i], attr->cmap.id_range_offset[i]));
1130 HPDF_TTFontDef_GetGlyphid (HPDF_FontDef fontdef,
1131 HPDF_UINT16 unicode)
1133 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1134 HPDF_UINT16 *pend_count = attr->cmap.end_count;
1135 HPDF_UINT seg_count = attr->cmap.seg_count_x2 / 2;
1138 HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid\n"));
1141 if (attr->cmap.format == 0) {
1143 return attr->cmap.glyph_id_array[unicode];
1147 if (attr->cmap.seg_count_x2 == 0) {
1148 HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_CMAP, 0);
1152 for (i = 0; i < seg_count; i++) {
1153 if (unicode <= *pend_count)
1158 if (attr->cmap.start_count[i] > unicode) {
1159 HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid undefined char(0x%04X)\n",
1164 if (attr->cmap.id_range_offset[i] == 0) {
1165 HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid idx=%u code=%u "
1166 " ret=%u\n", i, unicode,
1167 unicode + attr->cmap.id_delta[i]));
1169 return (HPDF_UINT16)(unicode + attr->cmap.id_delta[i]);
1171 HPDF_UINT idx = attr->cmap.id_range_offset[i] / 2 +
1172 (unicode - attr->cmap.start_count[i]) - (seg_count - i);
1174 if (idx > attr->cmap.glyph_id_array_count) {
1175 HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid[%u] %u > %u\n",
1176 i, idx, (HPDF_UINT)attr->cmap.glyph_id_array_count));
1179 HPDF_UINT16 gid = (HPDF_UINT16)(attr->cmap.glyph_id_array[idx] +
1180 attr->cmap.id_delta[i]);
1181 HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid idx=%u unicode=0x%04X "
1182 "id=%u\n", idx, unicode, gid));
1190 HPDF_TTFontDef_GetCharWidth (HPDF_FontDef fontdef,
1191 HPDF_UINT16 unicode)
1193 HPDF_UINT16 advance_width;
1194 HPDF_TTF_LongHorMetric hmetrics;
1195 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1196 HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, unicode);
1198 HPDF_PTRACE((" HPDF_TTFontDef_GetCharWidth\n"));
1200 if (gid >= attr->num_glyphs) {
1201 HPDF_PTRACE((" HPDF_TTFontDef_GetCharWidth WARNING gid > "
1202 "num_glyphs %u > %u\n", gid, attr->num_glyphs));
1203 return fontdef->missing_width;
1206 hmetrics = attr->h_metric[gid];
1208 if (!attr->glyph_tbl.flgs[gid]) {
1209 attr->glyph_tbl.flgs[gid] = 1;
1211 if (attr->embedding)
1212 CheckCompositGryph (fontdef, gid);
1215 advance_width = (HPDF_UINT16)((HPDF_UINT)hmetrics.advance_width * 1000 /
1216 attr->header.units_per_em);
1218 return (HPDF_INT16)advance_width;
1223 CheckCompositGryph (HPDF_FontDef fontdef,
1226 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1227 HPDF_UINT offset = attr->glyph_tbl.offsets[gid];
1228 /* HPDF_UINT len = attr->glyph_tbl.offsets[gid + 1] - offset; */
1231 HPDF_PTRACE ((" CheckCompositGryph\n"));
1233 if (attr->header.index_to_loc_format == 0)
1236 offset += attr->glyph_tbl.base_offset;
1238 if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET))
1242 HPDF_INT16 num_of_contours;
1244 HPDF_INT16 glyph_index;
1245 const HPDF_UINT16 ARG_1_AND_2_ARE_WORDS = 1;
1246 const HPDF_UINT16 WE_HAVE_A_SCALE = 8;
1247 const HPDF_UINT16 MORE_COMPONENTS = 32;
1248 const HPDF_UINT16 WE_HAVE_AN_X_AND_Y_SCALE = 64;
1249 const HPDF_UINT16 WE_HAVE_A_TWO_BY_TWO = 128;
1251 if ((ret = GetINT16 (attr->stream, &num_of_contours)) != HPDF_OK)
1254 if (num_of_contours != -1)
1257 HPDF_PTRACE ((" CheckCompositGryph composit font gid=%u\n", gid));
1259 if ((ret = HPDF_Stream_Seek (attr->stream, 8, HPDF_SEEK_CUR))
1264 if ((ret = GetINT16 (attr->stream, &flags)) != HPDF_OK)
1267 if ((ret = GetINT16 (attr->stream, &glyph_index)) != HPDF_OK)
1270 if (flags & ARG_1_AND_2_ARE_WORDS) {
1271 if ((ret = HPDF_Stream_Seek (attr->stream, 4, HPDF_SEEK_CUR))
1275 if ((ret = HPDF_Stream_Seek (attr->stream, 2, HPDF_SEEK_CUR))
1280 if (flags & WE_HAVE_A_SCALE) {
1281 if ((ret = HPDF_Stream_Seek (attr->stream, 2, HPDF_SEEK_CUR))
1284 } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
1285 if ((ret = HPDF_Stream_Seek (attr->stream, 4, HPDF_SEEK_CUR))
1288 } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
1289 if ((ret = HPDF_Stream_Seek (attr->stream, 8, HPDF_SEEK_CUR))
1294 if (glyph_index > 0 && glyph_index < attr->num_glyphs)
1295 attr->glyph_tbl.flgs[glyph_index] = 1;
1297 HPDF_PTRACE ((" gid=%d, num_of_contours=%d, flags=%d, "
1298 "glyph_index=%d\n", gid, num_of_contours, flags,
1301 } while (flags & MORE_COMPONENTS);
1309 HPDF_TTFontDef_GetGidWidth (HPDF_FontDef fontdef,
1312 HPDF_UINT16 advance_width;
1313 HPDF_TTF_LongHorMetric hmetrics;
1314 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1316 HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth\n"));
1318 if (gid >= attr->num_glyphs) {
1319 HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth WARNING gid > "
1320 "num_glyphs %u > %u\n", gid, attr->num_glyphs));
1321 return fontdef->missing_width;
1324 hmetrics = attr->h_metric[gid];
1326 advance_width = (HPDF_UINT16)((HPDF_UINT)hmetrics.advance_width * 1000 /
1327 attr->header.units_per_em);
1329 HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth gid=%u, width=%u\n",
1330 gid, advance_width));
1332 return (HPDF_INT16)advance_width;
1338 ParseHmtx (HPDF_FontDef fontdef)
1340 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1341 HPDF_TTFTable *tbl = FindTable (fontdef, "hmtx");
1344 HPDF_UINT16 save_aw = 0;
1345 HPDF_TTF_LongHorMetric *pmetric;
1347 HPDF_PTRACE ((" HPDF_TTFontDef_ParseHtmx\n"));
1350 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 7);
1352 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1356 /* allocate memory for a table of holizontal matrix.
1357 * the count of metric records is same as the number of glyphs
1359 attr->h_metric = HPDF_GetMem (fontdef->mmgr,
1360 sizeof (HPDF_TTF_LongHorMetric) * attr->num_glyphs);
1362 if (!attr->h_metric)
1363 return HPDF_Error_GetCode (fontdef->error);
1365 pmetric = attr->h_metric;
1366 for (i = 0; i < attr->num_h_metric; i++) {
1367 if ((ret = GetUINT16 (attr->stream, &pmetric->advance_width)) !=
1371 if ((ret = GetINT16 (attr->stream, &pmetric->lsb)) != HPDF_OK)
1374 HPDF_PTRACE((" ParseHmtx metric[%u] aw=%u lsb=%d\n", i,
1375 pmetric->advance_width, pmetric->lsb));
1377 save_aw = pmetric->advance_width;
1381 /* pad the advance_width of remaining metrics with the value of last metric */
1382 while (i < attr->num_glyphs) {
1383 pmetric->advance_width = save_aw;
1385 if ((ret = GetINT16 (attr->stream, &pmetric->lsb)) != HPDF_OK)
1396 ParseLoca (HPDF_FontDef fontdef)
1398 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1399 HPDF_TTFTable *tbl = FindTable (fontdef, "loca");
1402 HPDF_UINT32 *poffset;
1404 HPDF_PTRACE ((" HPDF_TTFontDef_ParseLoca\n"));
1407 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 8);
1409 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1413 /* allocate glyph-offset-table. */
1414 attr->glyph_tbl.offsets = HPDF_GetMem (fontdef->mmgr,
1415 sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1417 if (!attr->glyph_tbl.offsets)
1418 return HPDF_Error_GetCode (fontdef->error);
1420 HPDF_MemSet (attr->glyph_tbl.offsets, 0,
1421 sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1423 /* allocate glyph-flg-table.
1424 * this flgs are used to judge whether glyphs should be embedded.
1426 attr->glyph_tbl.flgs = HPDF_GetMem (fontdef->mmgr,
1427 sizeof (HPDF_BYTE) * attr->num_glyphs);
1429 if (!attr->glyph_tbl.flgs)
1430 return HPDF_Error_GetCode (fontdef->error);
1432 HPDF_MemSet (attr->glyph_tbl.flgs, 0,
1433 sizeof (HPDF_BYTE) * attr->num_glyphs);
1434 attr->glyph_tbl.flgs[0] = 1;
1436 poffset = attr->glyph_tbl.offsets;
1437 if (attr->header.index_to_loc_format == 0) {
1439 for (i = 0; i <= attr->num_glyphs; i++) {
1440 HPDF_UINT16 tmp = 0;
1442 if ((ret = GetUINT16 (attr->stream, &tmp)) != HPDF_OK)
1450 for (i = 0; i <= attr->num_glyphs; i++) {
1451 if ((ret = GetUINT32 (attr->stream, poffset)) != HPDF_OK)
1459 #ifdef LIBHPDF_DEBUG
1460 poffset = attr->glyph_tbl.offsets;
1461 for (i = 0; i <= attr->num_glyphs; i++) {
1462 HPDF_PTRACE((" ParseLOCA offset[%u]=%u\n", i, (HPDF_UINT)*poffset));
1473 LoadUnicodeName (HPDF_Stream stream,
1478 HPDF_BYTE tmp[HPDF_LIMIT_MAX_NAME_LEN * 2 + 1];
1483 HPDF_MemSet (buf, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1485 if ((ret = HPDF_Stream_Seek (stream, offset, HPDF_SEEK_SET)) !=
1489 if ((ret = HPDF_Stream_Read (stream, tmp, &len))
1504 ParseName (HPDF_FontDef fontdef)
1506 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1507 HPDF_TTFTable *tbl = FindTable (fontdef, "name");
1510 HPDF_TTF_NameRecord *name_rec;
1511 HPDF_UINT offset_id1 = 0;
1512 HPDF_UINT offset_id2 = 0;
1513 HPDF_UINT offset_id1u = 0;
1514 HPDF_UINT offset_id2u = 0;
1515 HPDF_UINT len_id1 = 0;
1516 HPDF_UINT len_id2 = 0;
1517 HPDF_UINT len_id1u = 0;
1518 HPDF_UINT len_id2u = 0;
1519 char tmp[HPDF_LIMIT_MAX_NAME_LEN + 1];
1521 HPDF_PTRACE ((" HPDF_TTFontDef_ParseMaxp\n"));
1524 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 10);
1526 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1530 ret += GetUINT16 (attr->stream, &attr->name_tbl.format);
1531 ret += GetUINT16 (attr->stream, &attr->name_tbl.count);
1532 ret += GetUINT16 (attr->stream, &attr->name_tbl.string_offset);
1534 return HPDF_Error_GetCode (fontdef->error);
1536 HPDF_PTRACE((" ParseName() format=%u, count=%u, string_offset=%u\n",
1537 attr->name_tbl.format, attr->name_tbl.count,
1538 attr->name_tbl.string_offset));
1540 attr->name_tbl.name_records = HPDF_GetMem (fontdef->mmgr,
1541 sizeof (HPDF_TTF_NameRecord) * attr->name_tbl.count);
1543 if (!attr->name_tbl.name_records)
1544 return HPDF_Error_GetCode (fontdef->error);
1546 name_rec = attr->name_tbl.name_records;
1548 for (i = 0; i < attr->name_tbl.count; i++) {
1549 ret += GetUINT16 (attr->stream, &name_rec->platform_id);
1550 ret += GetUINT16 (attr->stream, &name_rec->encoding_id);
1551 ret += GetUINT16 (attr->stream, &name_rec->language_id);
1552 ret += GetUINT16 (attr->stream, &name_rec->name_id);
1553 ret += GetUINT16 (attr->stream, &name_rec->length);
1554 ret += GetUINT16 (attr->stream, &name_rec->offset);
1557 return HPDF_Error_GetCode (fontdef->error);
1559 HPDF_PTRACE((" ParseName() platformID=%u, encodingID=%d, nameID=%d\n",
1560 name_rec->platform_id, name_rec->encoding_id,
1561 name_rec->name_id));
1563 if (name_rec->platform_id == 1 && name_rec->encoding_id == 0 &&
1564 name_rec->name_id == 6) {
1565 offset_id1 = tbl->offset + name_rec->offset +
1566 attr->name_tbl.string_offset;
1567 len_id1 = name_rec->length;
1570 if (name_rec->platform_id == 1 && name_rec->encoding_id == 0 &&
1571 name_rec->name_id == 2) {
1572 offset_id2 = tbl->offset + name_rec->offset +
1573 attr->name_tbl.string_offset;
1574 len_id2 = name_rec->length;
1577 if (name_rec->platform_id == 3 && name_rec->encoding_id == 1 &&
1578 name_rec->name_id == 6 && name_rec->language_id == 0x0409) {
1579 offset_id1u = tbl->offset + name_rec->offset +
1580 attr->name_tbl.string_offset;
1581 len_id1u = name_rec->length;
1584 if (name_rec->platform_id == 3 && name_rec->encoding_id == 1 &&
1585 name_rec->name_id == 2 && name_rec->language_id == 0x0409) {
1586 offset_id2u = tbl->offset + name_rec->offset +
1587 attr->name_tbl.string_offset;
1588 len_id2u = name_rec->length;
1594 if ((!offset_id1 && !offset_id1u) ||
1595 (!offset_id2 && !offset_id2u))
1596 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1598 if (len_id1 == 0 && len_id1u > 0)
1599 len_id1 = len_id1u / 2 + len_id1u % 2;
1601 if (len_id2 == 0 && len_id2u > 0)
1602 len_id2 = len_id2u / 2 + len_id2u % 2;
1604 if (len_id1 + len_id2 + 8 > 127)
1605 return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1607 HPDF_MemSet (attr->base_font, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1610 if ((ret = HPDF_Stream_Seek (attr->stream, offset_id1,
1611 HPDF_SEEK_SET)) != HPDF_OK)
1614 if ((ret = HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)attr->base_font, &len_id1))
1618 if ((ret = LoadUnicodeName (attr->stream, offset_id1u, len_id1u,
1619 attr->base_font)) != HPDF_OK)
1623 HPDF_MemSet (tmp, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1626 if ((ret = HPDF_Stream_Seek (attr->stream, offset_id2, HPDF_SEEK_SET))
1630 if ((ret = HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)tmp, &len_id2)) != HPDF_OK)
1633 if ((ret = LoadUnicodeName (attr->stream, offset_id2u, len_id2u,
1639 * get "postscript name" of from a "name" table as BaseName.
1640 * if subfamily name is not "Regular", add subfamily name to BaseName.
1641 * if subfamily name includes the blank character, remove it.
1642 * if subfamily name is "Bold" or "Italic" or "BoldItalic", set flags
1645 if (HPDF_MemCmp ((HPDF_BYTE *)tmp, (HPDF_BYTE *)"Regular", 7) != 0) {
1646 char *dst = attr->base_font + len_id1;
1652 for (j = 0; j < len_id2; j++) {
1656 if (dst >= attr->base_font + HPDF_LIMIT_MAX_NAME_LEN)
1662 if (HPDF_StrStr (tmp, "Bold", len_id2))
1663 fontdef->flags |= HPDF_FONT_FOURCE_BOLD;
1664 if (HPDF_StrStr (tmp, "Italic", len_id2))
1665 fontdef->flags |= HPDF_FONT_ITALIC;
1668 HPDF_MemCpy ((HPDF_BYTE *)fontdef->base_font, (HPDF_BYTE *)attr->base_font, HPDF_LIMIT_MAX_NAME_LEN + 1);
1670 HPDF_PTRACE((" ParseName() base_font=%s\n", attr->base_font));
1676 ParseOS2 (HPDF_FontDef fontdef)
1678 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1679 HPDF_TTFTable *tbl = FindTable (fontdef, "OS/2");
1683 HPDF_PTRACE ((" ParseOS2\n"));
1686 return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 0);
1688 ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 8, HPDF_SEEK_SET);
1692 /* check whether the font is allowed to be embedded. */
1693 if ((ret = GetUINT16 (attr->stream, &attr->fs_type)) != HPDF_OK)
1696 if (attr->fs_type & (0x0002 | 0x0100 | 0x0200) && attr->embedding)
1697 return HPDF_SetError (fontdef->error, HPDF_TTF_CANNOT_EMBEDDING_FONT,
1700 if ((ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 20, HPDF_SEEK_SET))
1705 if ((ret = HPDF_Stream_Read (attr->stream, attr->panose, &len)) != HPDF_OK)
1708 HPDF_PTRACE((" ParseOS2 PANOSE=%u-%u "
1709 "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
1710 attr->panose[0], attr->panose[1], attr->panose[2], attr->panose[3],
1711 attr->panose[4], attr->panose[5], attr->panose[6], attr->panose[7],
1712 attr->panose[8], attr->panose[9], attr->panose[10], attr->panose[11]));
1714 if (attr->panose[0] == 1 || attr->panose[0] == 4)
1715 fontdef->flags = fontdef->flags | HPDF_FONT_SERIF;
1717 /* get ulCodePageRange1 */
1718 if ((ret = HPDF_Stream_Seek (attr->stream, 78, HPDF_SEEK_CUR)) != HPDF_OK)
1721 if ((ret = GetUINT32 (attr->stream, &attr->code_page_range1)) != HPDF_OK)
1724 if ((ret = GetUINT32 (attr->stream, &attr->code_page_range2)) != HPDF_OK)
1727 HPDF_PTRACE((" ParseOS2 CodePageRange1=%08X CodePageRange2=%08X\n",
1728 (HPDF_UINT)attr->code_page_range1,
1729 (HPDF_UINT)attr->code_page_range2));
1736 RecreateGLYF (HPDF_FontDef fontdef,
1737 HPDF_UINT32 *new_offsets,
1740 HPDF_UINT32 save_offset = 0;
1741 HPDF_UINT32 start_offset = stream->size;
1742 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1746 HPDF_PTRACE ((" RecreateGLYF\n"));
1748 for (i = 0; i < attr->num_glyphs; i++) {
1749 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
1751 if (attr->glyph_tbl.flgs[i] == 1) {
1752 HPDF_UINT offset = attr->glyph_tbl.offsets[i];
1753 HPDF_UINT len = attr->glyph_tbl.offsets[i + 1] - offset;
1755 new_offsets[i] = stream->size - start_offset;
1756 if (attr->header.index_to_loc_format == 0) {
1757 new_offsets[i] /= 2;
1761 HPDF_PTRACE((" RecreateGLYF[%u] move from [%u] to [%u]\n", i,
1762 (HPDF_UINT)attr->glyph_tbl.base_offset + offset,
1763 (HPDF_UINT)new_offsets[i]));
1765 if (attr->header.index_to_loc_format == 0)
1768 offset += attr->glyph_tbl.base_offset;
1770 if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET))
1776 (len > HPDF_STREAM_BUF_SIZ) ? HPDF_STREAM_BUF_SIZ : len;
1778 HPDF_MemSet (buf, 0, tmp_len);
1780 if ((ret = HPDF_Stream_Read (attr->stream, buf, &tmp_len))
1784 if ((ret = HPDF_Stream_Write (stream, buf, tmp_len)) !=
1791 save_offset = stream->size - start_offset;
1792 if (attr->header.index_to_loc_format == 0)
1795 new_offsets[i] = save_offset;
1799 new_offsets[attr->num_glyphs] = save_offset;
1802 for (i = 0; i <= attr->num_glyphs; i++) {
1803 HPDF_PTRACE((" RecreateGLYF[%u] offset=%u\n", i, new_offsets[i]));
1811 RecreateName (HPDF_FontDef fontdef,
1814 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1815 HPDF_TTFTable *tbl = FindTable (fontdef, "name");
1816 HPDF_STATUS ret = HPDF_OK;
1818 HPDF_TTF_NameRecord *name_rec;
1819 HPDF_Stream tmp_stream = HPDF_MemStream_New (fontdef->mmgr,
1820 HPDF_STREAM_BUF_SIZ);
1822 HPDF_PTRACE ((" RecreateName\n"));
1825 return HPDF_Error_GetCode (fontdef->error);
1827 ret += WriteUINT16 (stream, attr->name_tbl.format);
1828 ret += WriteUINT16 (stream, attr->name_tbl.count);
1829 ret += WriteUINT16 (stream, attr->name_tbl.string_offset);
1831 if (ret != HPDF_OK) {
1832 HPDF_Stream_Free (tmp_stream);
1833 return HPDF_Error_GetCode (fontdef->error);
1836 name_rec = attr->name_tbl.name_records;
1837 for (i = 0; i < attr->name_tbl.count; i++) {
1838 HPDF_UINT name_len = name_rec->length;
1839 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
1840 HPDF_UINT tmp_len = name_len;
1841 HPDF_UINT offset = tbl->offset + attr->name_tbl.string_offset +
1843 HPDF_UINT rec_offset = tmp_stream->size;
1845 /* add suffix to font-name. */
1846 if (name_rec->name_id == 1 || name_rec->name_id == 4) {
1847 if (name_rec->platform_id == 0 || name_rec->platform_id == 3) {
1848 ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)attr->tag_name2,
1849 sizeof(attr->tag_name2));
1850 name_len += sizeof(attr->tag_name2);
1852 ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)attr->tag_name,
1853 sizeof(attr->tag_name));
1854 name_len += sizeof(attr->tag_name);
1858 ret += WriteUINT16 (stream, name_rec->platform_id);
1859 ret += WriteUINT16 (stream, name_rec->encoding_id);
1860 ret += WriteUINT16 (stream, name_rec->language_id);
1861 ret += WriteUINT16 (stream, name_rec->name_id);
1862 ret += WriteUINT16 (stream, (HPDF_UINT16)name_len);
1863 ret += WriteUINT16 (stream, (HPDF_UINT16)rec_offset);
1865 ret += HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET);
1867 if (ret != HPDF_OK) {
1868 HPDF_Stream_Free (tmp_stream);
1869 return HPDF_Error_GetCode (fontdef->error);
1872 while (tmp_len > 0) {
1873 HPDF_UINT len = (tmp_len > HPDF_STREAM_BUF_SIZ) ?
1874 HPDF_STREAM_BUF_SIZ : tmp_len;
1876 if ((ret = HPDF_Stream_Read (attr->stream, buf, &len)) != HPDF_OK) {
1877 HPDF_Stream_Free (tmp_stream);
1881 if ((ret = HPDF_Stream_Write (tmp_stream, buf, len)) != HPDF_OK) {
1882 HPDF_Stream_Free (tmp_stream);
1889 HPDF_PTRACE((" RecreateNAME name_rec[%u] platform_id=%u "
1890 "encoding_id=%u language_id=%u name_rec->name_id=%u "
1891 "length=%u offset=%u\n", i, name_rec->platform_id,
1892 name_rec->encoding_id, name_rec->language_id,
1893 name_rec->name_id, name_len, rec_offset));
1898 ret = HPDF_Stream_WriteToStream (tmp_stream, stream,
1899 HPDF_STREAM_FILTER_NONE, NULL);
1901 HPDF_Stream_Free (tmp_stream);
1908 WriteHeader (HPDF_FontDef fontdef,
1910 HPDF_UINT32 *check_sum_ptr)
1912 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1913 HPDF_STATUS ret = HPDF_OK;
1915 HPDF_PTRACE ((" WriteHeader\n"));
1917 ret += HPDF_Stream_Write (stream, attr->header.version_number, 4);
1918 ret += WriteUINT32 (stream, attr->header.font_revision);
1920 /* save the address of checkSumAdjustment.
1921 * the value is rewrite to computed value after new check-sum-value is
1924 *check_sum_ptr = stream->size;
1926 ret += WriteUINT32 (stream, 0);
1927 ret += WriteUINT32 (stream, attr->header.magic_number);
1928 ret += WriteUINT16 (stream, attr->header.flags);
1929 ret += WriteUINT16 (stream, attr->header.units_per_em);
1930 ret += HPDF_Stream_Write (stream, attr->header.created, 8);
1931 ret += HPDF_Stream_Write (stream, attr->header.modified, 8);
1932 ret += WriteINT16 (stream, attr->header.x_min);
1933 ret += WriteINT16 (stream, attr->header.y_min);
1934 ret += WriteINT16 (stream, attr->header.x_max);
1935 ret += WriteINT16 (stream, attr->header.y_max);
1936 ret += WriteUINT16 (stream, attr->header.mac_style);
1937 ret += WriteUINT16 (stream, attr->header.lowest_rec_ppem);
1938 ret += WriteINT16 (stream, attr->header.font_direction_hint);
1939 ret += WriteINT16 (stream, attr->header.index_to_loc_format);
1940 ret += WriteINT16 (stream, attr->header.glyph_data_format);
1943 return HPDF_Error_GetCode (fontdef->error);
1950 HPDF_TTFontDef_SaveFontData (HPDF_FontDef fontdef,
1953 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1954 HPDF_TTFTable tmp_tbl[HPDF_REQUIRED_TAGS_COUNT];
1955 HPDF_Stream tmp_stream;
1956 HPDF_UINT32 *new_offsets;
1958 HPDF_UINT32 check_sum_ptr = 0;
1960 HPDF_UINT32 offset_base;
1961 HPDF_UINT32 tmp_check_sum = 0xB1B0AFBA;
1963 HPDF_PTRACE ((" SaveFontData\n"));
1965 ret = WriteUINT32 (stream, attr->offset_tbl.sfnt_version);
1966 ret += WriteUINT16 (stream, HPDF_REQUIRED_TAGS_COUNT);
1967 ret += WriteUINT16 (stream, attr->offset_tbl.search_range);
1968 ret += WriteUINT16 (stream, attr->offset_tbl.entry_selector);
1969 ret += WriteUINT16 (stream, attr->offset_tbl.range_shift);
1972 return HPDF_Error_GetCode (fontdef->error);
1974 tmp_stream = HPDF_MemStream_New (fontdef->mmgr, HPDF_STREAM_BUF_SIZ);
1976 return HPDF_Error_GetCode (fontdef->error);
1978 offset_base = 12 + 16 * HPDF_REQUIRED_TAGS_COUNT;
1980 new_offsets = HPDF_GetMem (fontdef->mmgr,
1981 sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1983 HPDF_Stream_Free (tmp_stream);
1984 return HPDF_Error_GetCode (fontdef->error);
1987 for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
1988 HPDF_TTFTable *tbl = FindTable (fontdef, REQUIRED_TAGS[i]);
1990 HPDF_UINT new_offset;
1991 HPDF_UINT32 *poffset;
1995 ret = HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, i);
1999 ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
2003 length = tbl->length;
2004 new_offset = tmp_stream->size;
2006 if (HPDF_MemCmp ((HPDF_BYTE *)tbl->tag, (HPDF_BYTE *)"head", 4) == 0) {
2007 ret = WriteHeader (fontdef, tmp_stream, &check_sum_ptr);
2008 } else if (HPDF_MemCmp ((HPDF_BYTE *)tbl->tag, (HPDF_BYTE *)"glyf", 4) == 0) {
2009 ret = RecreateGLYF (fontdef, new_offsets, tmp_stream);
2010 } else if (HPDF_MemCmp ((HPDF_BYTE *)tbl->tag, (HPDF_BYTE *)"loca", 4) == 0) {
2013 HPDF_MemSet (&value, 0, 4);
2014 poffset = new_offsets;
2016 if (attr->header.index_to_loc_format == 0) {
2017 for (j = 0; j <= attr->num_glyphs; j++) {
2018 ret += WriteUINT16 (tmp_stream, (HPDF_UINT16)*poffset);
2022 for (j = 0; j <= attr->num_glyphs; j++) {
2023 ret += WriteUINT32 (tmp_stream, *poffset);
2027 } else if (HPDF_MemCmp ((HPDF_BYTE *)tbl->tag, (HPDF_BYTE *)"name", 4) == 0) {
2028 ret = RecreateName (fontdef, tmp_stream);
2032 while (length > 4) {
2035 ret = HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)&value, &size);
2036 ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)&value, size);
2042 ret += HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)&value, &size);
2043 ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)&value, size);
2046 tmp_tbl[i].offset = new_offset;
2047 tmp_tbl[i].length = tmp_stream->size - new_offset;
2053 /* recalcurate checksum */
2054 for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
2055 HPDF_TTFTable tbl = tmp_tbl[i];
2057 HPDF_UINT length = tbl.length;
2059 HPDF_PTRACE((" SaveFontData() tag[%s] length=%u\n",
2060 REQUIRED_TAGS[i], length));
2062 if ((ret = HPDF_Stream_Seek (tmp_stream, tbl.offset, HPDF_SEEK_SET))
2067 while (length > 0) {
2068 HPDF_UINT rlen = (length > 4) ? 4 : length;
2070 if ((ret = HPDF_Stream_Read (tmp_stream, (HPDF_BYTE *)&buf, &rlen))
2075 tbl.check_sum += buf;
2082 HPDF_PTRACE((" SaveFontData tag[%s] check-sum=%u offset=%u\n",
2083 REQUIRED_TAGS[i], (HPDF_UINT)tbl.check_sum,
2084 (HPDF_UINT)tbl.offset));
2086 ret += HPDF_Stream_Write (stream, (HPDF_BYTE *)REQUIRED_TAGS[i], 4);
2087 ret += WriteUINT32 (stream, tbl.check_sum);
2088 tbl.offset += offset_base;
2089 ret += WriteUINT32 (stream, tbl.offset);
2090 ret += WriteUINT32 (stream, tbl.length);
2099 /* calucurate checkSumAdjustment.*/
2100 ret = HPDF_Stream_Seek (tmp_stream, 0, HPDF_SEEK_SET);
2106 HPDF_UINT siz = sizeof(buf);
2108 ret = HPDF_Stream_Read (tmp_stream, (HPDF_BYTE *)&buf, &siz);
2109 if (ret != HPDF_OK || siz <= 0) {
2110 if (ret == HPDF_STREAM_EOF)
2116 tmp_check_sum -= buf;
2122 HPDF_PTRACE((" SaveFontData new checkSumAdjustment=%u\n",
2123 (HPDF_UINT)tmp_check_sum));
2125 UINT32Swap (&tmp_check_sum);
2127 ret = HPDF_Stream_Seek (tmp_stream, check_sum_ptr, HPDF_SEEK_SET);
2128 if (ret == HPDF_OK) {
2129 ret = HPDF_MemStream_Rewrite (tmp_stream, (HPDF_BYTE *)&tmp_check_sum,
2136 attr->length1 = tmp_stream->size + offset_base;
2137 ret = HPDF_Stream_WriteToStream (tmp_stream, stream, 0, NULL);
2142 HPDF_FreeMem (fontdef->mmgr, new_offsets);
2143 HPDF_Stream_Free (tmp_stream);
2148 HPDF_TTFontDef_SetTagName (HPDF_FontDef fontdef,
2151 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
2152 char buf[HPDF_LIMIT_MAX_NAME_LEN + 1];
2155 HPDF_PTRACE ((" HPDF_TTFontDef_SetTagName\n"));
2157 if (HPDF_StrLen (tag, HPDF_LIMIT_MAX_NAME_LEN) != HPDF_TTF_FONT_TAG_LEN)
2160 HPDF_MemCpy ((HPDF_BYTE *)attr->tag_name, (HPDF_BYTE *)tag, HPDF_TTF_FONT_TAG_LEN);
2161 attr->tag_name[HPDF_TTF_FONT_TAG_LEN] = '+';
2163 for (i = 0; i < HPDF_TTF_FONT_TAG_LEN + 1; i++) {
2164 attr->tag_name2[i * 2] = 0x00;
2165 attr->tag_name2[i * 2 + 1] = attr->tag_name[i];
2168 HPDF_MemSet (buf, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
2169 HPDF_MemCpy ((HPDF_BYTE *)buf, (HPDF_BYTE *)attr->tag_name, HPDF_TTF_FONT_TAG_LEN + 1);
2170 HPDF_MemCpy ((HPDF_BYTE *)buf + HPDF_TTF_FONT_TAG_LEN + 1, (HPDF_BYTE *)fontdef->base_font, HPDF_LIMIT_MAX_NAME_LEN - HPDF_TTF_FONT_TAG_LEN - 1);
2172 HPDF_MemCpy ((HPDF_BYTE *)attr->base_font, (HPDF_BYTE *)buf, HPDF_LIMIT_MAX_NAME_LEN + 1);
2177 PdfTTFontDef::GetNameAttr(unsigned char* buf, HPDF_UINT name_id,
2178 HPDF_UINT platform_id, HPDF_UINT lang_id, HPDF_UINT max_len)
2183 static HPDF_TTFTable*
2184 FindTable (HPDF_FontDef fontdef,
2187 HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
2188 HPDF_TTFTable* tbl = attr->offset_tbl.table;
2191 for (i = 0; i < attr->offset_tbl.num_tables; i++, tbl++) {
2192 if (HPDF_MemCmp ((HPDF_BYTE *)tbl->tag, (HPDF_BYTE *)tag, 4) == 0) {
2193 HPDF_PTRACE((" FindTable find table[%c%c%c%c]\n",
2194 tbl->tag[0], tbl->tag[1], tbl->tag[2], tbl->tag[3]));
2203 UINT32Swap (HPDF_UINT32 *value)
2207 HPDF_MemCpy (b, (HPDF_BYTE *)value, 4);
2208 *value = (HPDF_UINT32)((HPDF_UINT32)b[0] << 24 |
2209 (HPDF_UINT32)b[1] << 16 |
2210 (HPDF_UINT32)b[2] << 8 |
2215 UINT16Swap (HPDF_UINT16 *value)
2219 HPDF_MemCpy (b, (HPDF_BYTE *)value, 2);
2220 *value = (HPDF_UINT16)((HPDF_UINT16)b[0] << 8 | (HPDF_UINT16)b[1]);
2224 INT16Swap (HPDF_INT16 *value)
2228 HPDF_MemCpy (b, (HPDF_BYTE *)value, 2);
2229 *value = (HPDF_INT16)((HPDF_INT16)b[0] << 8 | (HPDF_INT16)b[1]);