HPDF_FontDef HPDF_Type1FontDef_New (HPDF_MMgr mmgr) { HPDF_FontDef fontdef; HPDF_Type1FontDefAttr fontdef_attr; HPDF_PTRACE (" HPDF_Type1FontDef_New\n"); if (!mmgr) return NULL; fontdef = HPDF_GetMem (mmgr, sizeof(HPDF_FontDef_Rec)); if (!fontdef) return NULL; HPDF_MemSet (fontdef, 0, sizeof (HPDF_FontDef_Rec)); fontdef->sig_bytes = HPDF_FONTDEF_SIG_BYTES; fontdef->mmgr = mmgr; fontdef->error = mmgr->error; fontdef->type = HPDF_FONTDEF_TYPE_TYPE1; fontdef->free_fn = FreeFunc; fontdef_attr = HPDF_GetMem (mmgr, sizeof(HPDF_Type1FontDefAttr_Rec)); if (!fontdef_attr) { HPDF_FreeMem (fontdef->mmgr, fontdef); return NULL; } fontdef->attr = fontdef_attr; HPDF_MemSet ((HPDF_BYTE *)fontdef_attr, 0, sizeof(HPDF_Type1FontDefAttr_Rec)); fontdef->flags = HPDF_FONT_STD_CHARSET; return fontdef; }
HPDF_FontDef HPDF_CIDFontDef_New (HPDF_MMgr mmgr, char *name, HPDF_FontDef_InitFunc init_fn) { HPDF_FontDef fontdef; HPDF_CIDFontDefAttr fontdef_attr; HPDF_PTRACE (" HPDF_CIDFontDef_New\n"); if (!mmgr) return NULL; fontdef = HPDF_GetMem (mmgr, sizeof(HPDF_FontDef_Rec)); if (!fontdef) return NULL; HPDF_MemSet (fontdef, 0, sizeof(HPDF_FontDef_Rec)); fontdef->sig_bytes = HPDF_FONTDEF_SIG_BYTES; HPDF_StrCpy (fontdef->base_font, name, fontdef->base_font + HPDF_LIMIT_MAX_NAME_LEN); fontdef->mmgr = mmgr; fontdef->error = mmgr->error; fontdef->type = HPDF_FONTDEF_TYPE_UNINITIALIZED; fontdef->free_fn = HPDF_CIDFontDef_FreeFunc; fontdef->init_fn = init_fn; fontdef->valid = HPDF_FALSE; fontdef_attr = HPDF_GetMem (mmgr, sizeof(HPDF_CIDFontDefAttr_Rec)); if (!fontdef_attr) { HPDF_FreeMem (fontdef->mmgr, fontdef); return NULL; } fontdef->attr = fontdef_attr; HPDF_MemSet ((HPDF_BYTE *)fontdef_attr, 0, sizeof(HPDF_CIDFontDefAttr_Rec)); fontdef_attr->widths = HPDF_List_New (mmgr, HPDF_DEF_CHAR_WIDTHS_NUM); if (!fontdef_attr->widths) { HPDF_FreeMem (fontdef->mmgr, fontdef); HPDF_FreeMem (fontdef->mmgr, fontdef_attr); return NULL; } fontdef->missing_width = 500; fontdef_attr->DW = 1000; fontdef_attr->DW2[0] = 880; fontdef_attr->DW2[1] = -1000; return fontdef; }
HPDF_String HPDF_String_New (HPDF_MMgr mmgr, const char *value, HPDF_Encoder encoder) { HPDF_String obj; HPDF_PTRACE((" HPDF_String_New\n")); obj = (HPDF_String)HPDF_GetMem (mmgr, sizeof(HPDF_String_Rec)); if (obj) { HPDF_MemSet (&obj->header, 0, sizeof(HPDF_Obj_Header)); obj->header.obj_class = HPDF_OCLASS_STRING; obj->mmgr = mmgr; obj->error = mmgr->error; obj->encoder = encoder; obj->value = NULL; obj->len = 0; if (HPDF_String_SetValue (obj, value) != HPDF_OK) { HPDF_FreeMem (obj->mmgr, obj); return NULL; } } return obj; }
HPDF_Binary HPDF_Binary_New (HPDF_MMgr mmgr, HPDF_BYTE *value, HPDF_UINT len) { HPDF_Binary obj; obj = HPDF_GetMem (mmgr, sizeof(HPDF_Binary_Rec)); if (obj) { HPDF_MemSet(&obj->header, 0, sizeof(HPDF_Obj_Header)); obj->header.obj_class = HPDF_OCLASS_BINARY; obj->mmgr = mmgr; obj->error = mmgr->error; obj->value = NULL; obj->len = 0; if (HPDF_Binary_SetValue (obj, value, len) != HPDF_OK) { HPDF_FreeMem (mmgr, obj); return NULL; } } return obj; }
void HPDF_Error_Init (HPDF_Error error, void *user_data) { HPDF_MemSet(error, 0, sizeof(HPDF_Error_Rec)); error->user_data = user_data; }
HPDF_Page HPDF_Page_New (HPDF_MMgr mmgr, HPDF_Xref xref) { HPDF_STATUS ret; HPDF_PageAttr attr; HPDF_Page page; HPDF_PTRACE((" HPDF_Page_New\n")); page = HPDF_Dict_New (mmgr); if (!page) return NULL; page->header.obj_class |= HPDF_OSUBCLASS_PAGE; page->free_fn = Page_OnFree; page->before_write_fn = Page_BeforeWrite; attr = HPDF_GetMem (page->mmgr, sizeof(HPDF_PageAttr_Rec)); if (!attr) { HPDF_Dict_Free (page); return NULL; } page->attr = attr; HPDF_MemSet (attr, 0, sizeof(HPDF_PageAttr_Rec)); attr->gmode = HPDF_GMODE_PAGE_DESCRIPTION; attr->cur_pos = HPDF_ToPoint (0, 0); attr->text_pos = HPDF_ToPoint (0, 0); ret = HPDF_Xref_Add (xref, page); if (ret != HPDF_OK) return NULL; attr->gstate = HPDF_GState_New (page->mmgr, NULL); attr->contents = HPDF_DictStream_New (page->mmgr, xref); if (!attr->gstate || !attr->contents) return NULL; attr->stream = attr->contents->stream; attr->xref = xref; /* add requiered elements */ ret += HPDF_Dict_AddName (page, "Type", "Page"); ret += HPDF_Dict_Add (page, "MediaBox", HPDF_Box_Array_New (page->mmgr, HPDF_ToBox (0, 0, (HPDF_INT16)(HPDF_DEF_PAGE_WIDTH), (HPDF_INT16)(HPDF_DEF_PAGE_HEIGHT)))); ret += HPDF_Dict_Add (page, "Contents", attr->contents); ret += AddResource (page); if (ret != HPDF_OK) return NULL; return page; }
HPDF_Xref HPDF_Xref_New (HPDF_MMgr mmgr, HPDF_UINT32 offset) { HPDF_Xref xref; HPDF_XrefEntry new_entry; HPDF_PTRACE((" HPDF_Xref_New\n")); xref = (HPDF_Xref)HPDF_GetMem (mmgr, sizeof(HPDF_Xref_Rec)); if (!xref) return NULL; HPDF_MemSet (xref, 0, sizeof(HPDF_Xref_Rec)); xref->mmgr = mmgr; xref->error = mmgr->error; xref->start_offset = offset; xref->entries = HPDF_List_New (mmgr, HPDF_DEFALUT_XREF_ENTRY_NUM); if (!xref->entries) goto Fail; xref->addr = 0; if (xref->start_offset == 0) { new_entry = (HPDF_XrefEntry)HPDF_GetMem (mmgr, sizeof(HPDF_XrefEntry_Rec)); if (!new_entry) goto Fail; if (HPDF_List_Add (xref->entries, new_entry) != HPDF_OK) { HPDF_FreeMem (mmgr, new_entry); goto Fail; } /* add first entry which is free entry and whose generation * number is 0 */ new_entry->entry_typ = HPDF_FREE_ENTRY; new_entry->byte_offset = 0; new_entry->gen_no = HPDF_MAX_GENERATION_NUM; new_entry->obj = NULL; } xref->trailer = HPDF_Dict_New (mmgr); if (!xref->trailer) goto Fail; return xref; Fail: HPDF_PTRACE((" HPDF_Xref_New failed\n")); HPDF_Xref_Free (xref); return NULL; }
HPDF_NewEx (HPDF_Error_Handler user_error_fn, HPDF_Alloc_Func user_alloc_fn, HPDF_Free_Func user_free_fn, HPDF_UINT mem_pool_buf_size, void *user_data) { HPDF_Doc pdf; HPDF_MMgr mmgr; HPDF_Error_Rec tmp_error; HPDF_PTRACE ((" HPDF_NewEx\n")); /* initialize temporary-error object */ HPDF_Error_Init (&tmp_error, user_data); /* create memory-manager object */ mmgr = HPDF_MMgr_New (&tmp_error, mem_pool_buf_size, user_alloc_fn, user_free_fn); if (!mmgr) { HPDF_CheckError (&tmp_error); return NULL; } /* now create pdf_doc object */ pdf = HPDF_GetMem (mmgr, sizeof (HPDF_Doc_Rec)); if (!pdf) { HPDF_MMgr_Free (mmgr); HPDF_CheckError (&tmp_error); return NULL; } HPDF_MemSet (pdf, 0, sizeof (HPDF_Doc_Rec)); pdf->sig_bytes = HPDF_SIG_BYTES; pdf->mmgr = mmgr; pdf->pdf_version = HPDF_VER_13; pdf->compression_mode = HPDF_COMP_NONE; /* copy the data of temporary-error object to the one which is included in pdf_doc object */ pdf->error = tmp_error; /* switch the error-object of memory-manager */ mmgr->error = &pdf->error; if (HPDF_NewDoc (pdf) != HPDF_OK) { HPDF_Free (pdf); HPDF_CheckError (&tmp_error); return NULL; } pdf->error.error_fn = user_error_fn; return pdf; }
HPDF_Null HPDF_Null_New (HPDF_MMgr mmgr) { HPDF_Null obj = HPDF_GetMem (mmgr, sizeof(HPDF_Null_Rec)); if (obj) { HPDF_MemSet (&obj->header, 0, sizeof(HPDF_Obj_Header)); obj->header.obj_class = HPDF_OCLASS_NULL; } return obj; }
HPDF_Number HPDF_Number_New (HPDF_MMgr mmgr, HPDF_INT32 value) { HPDF_Number obj = (HPDF_Number)HPDF_GetMem (mmgr, sizeof(HPDF_Number_Rec)); if (obj) { HPDF_MemSet (&obj->header, 0, sizeof(HPDF_Obj_Header)); obj->header.obj_class = HPDF_OCLASS_NUMBER; obj->value = value; } return obj; }
HPDF_Real HPDF_Real_New (HPDF_MMgr mmgr, HPDF_REAL value) { HPDF_Real obj = HPDF_GetMem (mmgr, sizeof(HPDF_Real_Rec)); if (obj) { HPDF_MemSet (&obj->header, 0, sizeof(HPDF_Obj_Header)); obj->header.obj_class = HPDF_OCLASS_REAL; obj->error = mmgr->error; HPDF_Real_SetValue (obj, value); } return obj; }
HPDF_FreeDoc (HPDF_Doc pdf) { HPDF_PTRACE ((" HPDF_FreeDoc\n")); if (HPDF_Doc_Validate (pdf)) { if (pdf->xref) { HPDF_Xref_Free (pdf->xref); pdf->xref = NULL; } if (pdf->font_mgr) { HPDF_List_Free (pdf->font_mgr); pdf->font_mgr = NULL; } if (pdf->fontdef_list) CleanupFontDefList (pdf); HPDF_MemSet(pdf->ttfont_tag, 0, 6); pdf->pdf_version = HPDF_VER_13; pdf->outlines = NULL; pdf->catalog = NULL; pdf->root_pages = NULL; pdf->cur_pages = NULL; pdf->cur_page = NULL; pdf->encrypt_on = HPDF_FALSE; pdf->cur_page_num = 0; pdf->cur_encoder = NULL; pdf->def_encoder = NULL; pdf->page_per_pages = 0; if (pdf->page_list) { HPDF_List_Free (pdf->page_list); pdf->page_list = NULL; } pdf->encrypt_dict = NULL; pdf->info = NULL; HPDF_Error_Reset (&pdf->error); if (pdf->stream) { HPDF_Stream_Free (pdf->stream); pdf->stream = NULL; } } }
HPDF_Proxy HPDF_Proxy_New (HPDF_MMgr mmgr, void *obj) { HPDF_Proxy p = HPDF_GetMem (mmgr, sizeof(HPDF_Proxy_Rec)); HPDF_PTRACE((" HPDF_Proxy_New\n")); if (p) { HPDF_MemSet (&p->header, 0, sizeof(HPDF_Obj_Header)); p->header.obj_class = HPDF_OCLASS_PROXY; p->obj = obj; } return p; }
HPDF_STATUS HPDF_Type1FontDef_SetWidths (HPDF_FontDef fontdef, const HPDF_CharData* widths) { const HPDF_CharData* src = widths; HPDF_Type1FontDefAttr attr = (HPDF_Type1FontDefAttr)fontdef->attr; HPDF_CharData* dst; HPDF_UINT i = 0; HPDF_PTRACE (" HPDF_Type1FontDef_SetWidths\n"); FreeWidth (fontdef); while (src->unicode != 0xFFFF) { src++; i++; } attr->widths_count = i; dst = (HPDF_CharData*)HPDF_GetMem (fontdef->mmgr, sizeof(HPDF_CharData) * attr->widths_count); if (dst == NULL) return HPDF_Error_GetCode (fontdef->error); HPDF_MemSet (dst, 0, sizeof(HPDF_CharData) * attr->widths_count); attr->widths = dst; src = widths; for (i = 0; i < attr->widths_count; i++) { dst->char_cd = src->char_cd; dst->unicode = src->unicode; dst->width = src->width; if (dst->unicode == 0x0020) { fontdef->missing_width = src->width; } src++; dst++; } return HPDF_OK; }
static HPDF_STATUS ReadPngData_Interlaced (HPDF_Dict image, png_structp png_ptr, png_infop info_ptr) { png_uint_32 len = png_get_rowbytes(png_ptr, info_ptr); png_uint_32 height = png_get_image_height(png_ptr, info_ptr); png_bytep* row_pointers = HPDF_GetMem (image->mmgr, height * sizeof (png_bytep)); if (row_pointers) { HPDF_UINT i; HPDF_MemSet (row_pointers, 0, height * sizeof (png_bytep)); for (i = 0; i < (HPDF_UINT)height; i++) { row_pointers[i] = HPDF_GetMem (image->mmgr, len); if (image->error->error_no != HPDF_OK) break; } if (image->error->error_no == HPDF_OK) { png_read_image(png_ptr, row_pointers); if (image->error->error_no == HPDF_OK) { /* add this line */ for (i = 0; i < (HPDF_UINT)height; i++) { if (HPDF_Stream_Write (image->stream, row_pointers[i], len) != HPDF_OK) break; } } } /* clean up */ for (i = 0; i < (HPDF_UINT)height; i++) { HPDF_FreeMem (image->mmgr, row_pointers[i]); } HPDF_FreeMem (image->mmgr, row_pointers); } return image->error->error_no; }
HPDF_Array HPDF_Array_New (HPDF_MMgr mmgr) { HPDF_Array obj; HPDF_PTRACE((" HPDF_Array_New\n")); obj = HPDF_GetMem (mmgr, sizeof(HPDF_Array_Rec)); if (obj) { HPDF_MemSet (obj, 0, sizeof(HPDF_Array_Rec)); obj->header.obj_class = HPDF_OCLASS_ARRAY; obj->mmgr = mmgr; obj->error = mmgr->error; obj->list = HPDF_List_New (mmgr, HPDF_DEF_ITEMS_PER_BLOCK); if (!obj->list) { HPDF_FreeMem (mmgr, obj); obj = NULL; } } return obj; }
static void PngErrorFunc (png_structp png_ptr, const char *msg) { char error_number[16]; HPDF_UINT i; HPDF_STATUS detail_no; HPDF_Error error; /* pick out error-number from error message */ HPDF_MemSet (error_number, 0, 16); for (i = 0; i < 15; i++) { error_number[i] = *(msg + i); if (*(msg + i + 1) == ' ') break; } error = (HPDF_Error)png_get_error_ptr (png_ptr); detail_no = (HPDF_STATUS)HPDF_AToI (error_number); HPDF_SetError (error, HPDF_LIBPNG_ERROR, detail_no); }
static HPDF_STATUS PngBeforeWrite (HPDF_Dict obj) { HPDF_STATUS ret; png_byte header[HPDF_PNG_BYTES_TO_CHECK]; HPDF_UINT len = HPDF_PNG_BYTES_TO_CHECK; HPDF_Stream png_data; HPDF_String s; HPDF_PTRACE ((" PngBeforeWrite\n")); HPDF_MemStream_FreeData(obj->stream); s = HPDF_Dict_GetItem (obj, "_FILE_NAME", HPDF_OCLASS_STRING); if (!s) return HPDF_SetError (obj->error, HPDF_MISSING_FILE_NAME_ENTRY, 0); png_data = HPDF_FileReader_New (obj->mmgr, (const char *)(s->value)); if (!HPDF_Stream_Validate (png_data)) return obj->error->error_no; HPDF_MemSet (header, 0x00, HPDF_PNG_BYTES_TO_CHECK); ret = HPDF_Stream_Read (png_data, header, &len); if (ret != HPDF_OK || png_sig_cmp (header, (png_size_t)0, HPDF_PNG_BYTES_TO_CHECK)) { HPDF_Stream_Free(png_data); return HPDF_SetError (obj->error, HPDF_INVALID_PNG_IMAGE, 0); } if ((ret = LoadPngData (obj, NULL, png_data, HPDF_FALSE)) != HPDF_OK) { HPDF_Stream_Free(png_data); return ret; } HPDF_Stream_Free(png_data); return HPDF_OK; }
HPDF_Image HPDF_Image_LoadPngImage (HPDF_MMgr mmgr, HPDF_Stream png_data, HPDF_Xref xref, HPDF_BOOL delayed_loading) { HPDF_STATUS ret; HPDF_Dict image; png_byte header[HPDF_PNG_BYTES_TO_CHECK]; HPDF_UINT len = HPDF_PNG_BYTES_TO_CHECK; HPDF_PTRACE ((" HPDF_Image_LoadPngImage\n")); HPDF_MemSet (header, 0x00, HPDF_PNG_BYTES_TO_CHECK); ret = HPDF_Stream_Read (png_data, header, &len); if (ret != HPDF_OK || png_sig_cmp (header, (png_size_t)0, HPDF_PNG_BYTES_TO_CHECK)) { HPDF_SetError (mmgr->error, HPDF_INVALID_PNG_IMAGE, 0); return NULL; } image = HPDF_DictStream_New (mmgr, xref); if (!image) return NULL; image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT; ret += HPDF_Dict_AddName (image, "Type", "XObject"); ret += HPDF_Dict_AddName (image, "Subtype", "Image"); if (ret != HPDF_OK) return NULL; if (LoadPngData (image, xref, png_data, delayed_loading) != HPDF_OK) return NULL; return image; }
HPDF_STATUS HPDF_Info_SetInfoDateAttr (HPDF_Dict info, HPDF_InfoType type, HPDF_Date value) { char tmp[HPDF_DATE_TIME_STR_LEN + 1]; char* ptmp; const char* name = InfoTypeToName (type); HPDF_PTRACE((" HPDF_Info_SetInfoDateAttr\n")); if (type > HPDF_INFO_MOD_DATE) return HPDF_SetError (info->error, HPDF_INVALID_PARAMETER, 0); HPDF_MemSet (tmp, 0, HPDF_DATE_TIME_STR_LEN + 1); if (value.month < 1 || 12 < value.month || value.day < 1 || 23 < value.hour || 59 < value.minutes || 59 < value.seconds || (value.ind != '+' && value.ind != '-' && value.ind != 'Z' && value.ind != ' ') || 23 < value.off_hour || 59 < value.off_minutes) { return HPDF_SetError (info->error, HPDF_INVALID_DATE_TIME, 0); } switch (value.month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: if (value.day > 31) return HPDF_SetError (info->error, HPDF_INVALID_DATE_TIME, 0); break; case 4: case 6: case 9: case 11: if (value.day > 30) return HPDF_SetError (info->error, HPDF_INVALID_DATE_TIME, 0); break; case 2: if (value.day > 29 || (value.day == 29 && (value.year % 4 != 0 || (value.year % 100 == 0 && value.year % 400 != 0)))) return HPDF_SetError (info->error, HPDF_INVALID_DATE_TIME, 0); break; default: return HPDF_SetError (info->error, HPDF_INVALID_DATE_TIME, 0); } ptmp = (char *)HPDF_MemCpy ((HPDF_BYTE *)tmp, (HPDF_BYTE *)"D:", 2); ptmp = HPDF_IToA2 (ptmp, value.year, 5); ptmp = HPDF_IToA2 (ptmp, value.month, 3); ptmp = HPDF_IToA2 (ptmp, value.day, 3); ptmp = HPDF_IToA2 (ptmp, value.hour, 3); ptmp = HPDF_IToA2 (ptmp, value.minutes, 3); ptmp = HPDF_IToA2 (ptmp, value.seconds, 3); if (value.ind != ' ') { *ptmp++ = value.ind; ptmp = HPDF_IToA2 (ptmp, value.off_hour, 3); *ptmp++ = '\''; ptmp = HPDF_IToA2 (ptmp, value.off_minutes, 3); *ptmp++ = '\''; } *ptmp = 0; return HPDF_Dict_Add (info, name, HPDF_String_New (info->mmgr, tmp, NULL)); }
static HPDF_STATUS LoadAfm (HPDF_FontDef fontdef, HPDF_Stream stream) { HPDF_Type1FontDefAttr attr = (HPDF_Type1FontDefAttr)fontdef->attr; char buf[HPDF_TMP_BUF_SIZ]; HPDF_CharData* cdata; HPDF_STATUS ret; HPDF_UINT len; char keyword[HPDF_LIMIT_MAX_NAME_LEN + 1]; HPDF_UINT i; HPDF_PTRACE (" LoadAfm\n"); len = HPDF_TMP_BUF_SIZ; /* chaeck AFM header */ if ((ret = HPDF_Stream_ReadLn (stream, buf, &len)) != HPDF_OK) return ret; GetKeyword (buf, keyword, HPDF_LIMIT_MAX_NAME_LEN + 1); if (HPDF_StrCmp (keyword, "StartFontMetrics") != 0) return HPDF_INVALID_AFM_HEADER; /* Global Font Information */ for (;;) { const char *s; len = HPDF_TMP_BUF_SIZ; if ((ret = HPDF_Stream_ReadLn (stream, buf, &len)) != HPDF_OK) return ret; s = GetKeyword (buf, keyword, HPDF_LIMIT_MAX_NAME_LEN + 1); if (HPDF_StrCmp (keyword, "FontName") == 0) { HPDF_StrCpy (fontdef->base_font, s, fontdef->base_font + HPDF_LIMIT_MAX_NAME_LEN); } else if (HPDF_StrCmp (keyword, "Weight") == 0) { if (HPDF_StrCmp (s, "Bold") == 0) fontdef->flags |= HPDF_FONT_FOURCE_BOLD; } else if (HPDF_StrCmp (keyword, "IsFixedPitch") == 0) { if (HPDF_StrCmp (s, "true") == 0) fontdef->flags |= HPDF_FONT_FIXED_WIDTH; } else if (HPDF_StrCmp (keyword, "ItalicAngle") == 0) { fontdef->italic_angle = (HPDF_INT16)HPDF_AToI (s); if (fontdef->italic_angle != 0) fontdef->flags |= HPDF_FONT_ITALIC; } else if (HPDF_StrCmp (keyword, "CharacterSet") == 0) { HPDF_UINT len = HPDF_StrLen (s, HPDF_LIMIT_MAX_STRING_LEN); if (len > 0) { attr->char_set = HPDF_GetMem (fontdef->mmgr, len + 1); if (!attr->char_set) return HPDF_Error_GetCode (fontdef->error); HPDF_StrCpy (attr->char_set, s, attr->char_set + len); } } else if (HPDF_StrCmp (keyword, "FontBBox") == 0) { char buf[HPDF_INT_LEN + 1]; s = GetKeyword (s, buf, HPDF_INT_LEN + 1); fontdef->font_bbox.left = (HPDF_REAL)HPDF_AToI (buf); s = GetKeyword (s, buf, HPDF_INT_LEN + 1); fontdef->font_bbox.bottom = (HPDF_REAL)HPDF_AToI (buf); s = GetKeyword (s, buf, HPDF_INT_LEN + 1); fontdef->font_bbox.right = (HPDF_REAL)HPDF_AToI (buf); GetKeyword (s, buf, HPDF_INT_LEN + 1); fontdef->font_bbox.top = (HPDF_REAL)HPDF_AToI (buf); } else if (HPDF_StrCmp (keyword, "EncodingScheme") == 0) { HPDF_StrCpy (attr->encoding_scheme, s, attr->encoding_scheme + HPDF_LIMIT_MAX_NAME_LEN); } else if (HPDF_StrCmp (keyword, "CapHeight") == 0) { fontdef->cap_height = (HPDF_UINT16)HPDF_AToI (s); } else if (HPDF_StrCmp (keyword, "Ascender") == 0) { fontdef->ascent = (HPDF_INT16)HPDF_AToI (s); } else if (HPDF_StrCmp (keyword, "Descender") == 0) { fontdef->descent = (HPDF_INT16)HPDF_AToI (s); } else if (HPDF_StrCmp (keyword, "STDHW") == 0) { fontdef->stemh = (HPDF_UINT16)HPDF_AToI (s); } else if (HPDF_StrCmp (keyword, "STDHV") == 0) { fontdef->stemv = (HPDF_UINT16)HPDF_AToI (s); } else if (HPDF_StrCmp (keyword, "StartCharMetrics") == 0) { attr->widths_count = HPDF_AToI (s); break; } } cdata = (HPDF_CharData*)HPDF_GetMem (fontdef->mmgr, sizeof(HPDF_CharData) * attr->widths_count); if (cdata == NULL) return HPDF_Error_GetCode (fontdef->error); HPDF_MemSet (cdata, 0, sizeof(HPDF_CharData) * attr->widths_count); attr->widths = cdata; /* load CharMetrics */ for (i = 0; i < attr->widths_count; i++, cdata++) { const char *s; char buf2[HPDF_LIMIT_MAX_NAME_LEN + 1]; len = HPDF_TMP_BUF_SIZ; if ((ret = HPDF_Stream_ReadLn (stream, buf, &len)) != HPDF_OK) return ret; /* C default character code. */ s = GetKeyword (buf, buf2, HPDF_LIMIT_MAX_NAME_LEN + 1); if (HPDF_StrCmp (buf2, "CX") == 0) { /* not suppoted yet. */ return HPDF_SetError (fontdef->error, HPDF_INVALID_CHAR_MATRICS_DATA, 0); } else if (HPDF_StrCmp (buf2, "C") == 0) { s += 2; s = GetKeyword (s, buf2, HPDF_LIMIT_MAX_NAME_LEN + 1); HPDF_AToI (buf2); cdata->char_cd = (HPDF_INT16)HPDF_AToI (buf2); } else return HPDF_SetError (fontdef->error, HPDF_INVALID_CHAR_MATRICS_DATA, 0); /* WX Character width */ s = HPDF_StrStr (s, "WX ", 0); if (!s) return HPDF_SetError (fontdef->error, HPDF_INVALID_WX_DATA, 0); s += 3; s = GetKeyword (s, buf2, HPDF_LIMIT_MAX_NAME_LEN + 1); if (buf2[0] == 0) return HPDF_SetError (fontdef->error, HPDF_INVALID_WX_DATA, 0); cdata->width = (HPDF_INT16)HPDF_AToI (buf2); /* N PostScript language character name */ s = HPDF_StrStr (s, "N ", 0); if (!s) return HPDF_SetError (fontdef->error, HPDF_INVALID_N_DATA, 0); s += 2; GetKeyword (s, buf2, HPDF_LIMIT_MAX_NAME_LEN + 1); cdata->unicode = HPDF_GryphNameToUnicode (buf2); } return HPDF_OK; }
static HPDF_STATUS CIDFontType2_BeforeWrite_Func (HPDF_Dict obj) { HPDF_FontAttr font_attr = (HPDF_FontAttr)obj->attr; HPDF_FontDef def = font_attr->fontdef; HPDF_TTFontDefAttr def_attr = (HPDF_TTFontDefAttr)def->attr; HPDF_STATUS ret = 0; HPDF_Font font; HPDF_Encoder encoder = font_attr->encoder; HPDF_CMapEncoderAttr encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_Array array; HPDF_UINT i; HPDF_UNICODE tmp_map[65536]; HPDF_UINT16 max = 0; HPDF_PTRACE ((" CIDFontType2_BeforeWrite_Func\n")); font = font_attr->descendant_font; HPDF_MemSet (tmp_map, 0, sizeof(HPDF_UNICODE) * 65536); if (ret != HPDF_OK) return ret; for (i = 0; i < 256; i++) { HPDF_UINT j; for (j = 0; j < 256; j++) { if (encoder->to_unicode_fn == HPDF_CMapEncoder_ToUnicode) { HPDF_UINT16 cid = encoder_attr->cid_map[i][j]; if (cid != 0) { HPDF_UNICODE unicode = encoder_attr->unicode_map[i][j]; HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (def, unicode); tmp_map[cid] = gid; if (max < cid) max = cid; } } else { HPDF_UNICODE unicode = (i << 8) | j; HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (def, unicode); tmp_map[unicode] = gid; if (max < unicode) max = unicode; } } } if (def_attr->is_cidfont) { max = def_attr->num_glyphs; } if (max > 0) { HPDF_INT16 dw = def->missing_width; HPDF_UNICODE *ptmp_map = tmp_map; HPDF_Array tmp_array = NULL; /* add 'W' element */ array = HPDF_Array_New (font->mmgr); if (!array) return HPDF_FAILD_TO_ALLOC_MEM; if (HPDF_Dict_Add (font, "W", array) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; for (i = 0; i < max; i++) { HPDF_INT w; HPDF_UINT16 gid; if (def_attr->is_cidfont) { gid = i; } else { gid = *ptmp_map; ptmp_map++; } w = HPDF_TTFontDef_GetGidWidth (def, gid); if (def_attr->glyph_tbl.flgs[gid] && w != dw) { if (!tmp_array) { if (HPDF_Array_AddNumber (array, i) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; tmp_array = HPDF_Array_New (font->mmgr); if (!tmp_array) return HPDF_FAILD_TO_ALLOC_MEM; if (HPDF_Array_Add (array, tmp_array) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; } if ((ret = HPDF_Array_AddNumber (tmp_array, w)) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; } else tmp_array = NULL; } /* create "CIDToGIDMap" data */ if (def_attr->embedding) { if (def_attr->is_cidfont) { ret += HPDF_Dict_AddName (font, "CIDToGIDMap", "Identity"); } else { font_attr->map_stream = HPDF_DictStream_New (font->mmgr, font_attr->xref); if (!font_attr->map_stream) return HPDF_FAILD_TO_ALLOC_MEM; if (HPDF_Dict_Add (font, "CIDToGIDMap", font_attr->map_stream) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; for (i = 0; i < max; i++) { HPDF_BYTE u[2]; HPDF_UINT16 gid = tmp_map[i]; u[0] = (HPDF_BYTE)(gid >> 8); u[1] = (HPDF_BYTE)gid; HPDF_MemCpy ((HPDF_BYTE *)(tmp_map + i), u, 2); } if ((ret = HPDF_Stream_Write (font_attr->map_stream->stream, (HPDF_BYTE *)tmp_map, max * 2)) != HPDF_OK) return HPDF_FAILD_TO_ALLOC_MEM; } } } else {
HPDF_Font HPDF_Type3RasterFont_New(HPDF_MMgr mmgr, HPDF_FontDef fontdef, HPDF_Encoder encoder, HPDF_Xref xref) { HPDF_Dict font; HPDF_FontAttr attr; HPDF_Type3RasterFontDefAttr fontdef_attr; HPDF_BasicEncoderAttr encoder_attr; HPDF_STATUS ret = 0; HPDF_UINT i; HPDF_PTRACE((" HPDF_Type3RasterFont_New\n")); /* check whether the fontdef object and the encoder object is valid. */ if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) { HPDF_SetError(mmgr->error, HPDF_INVALID_ENCODER_TYPE, 0); return NULL; } if (fontdef->type != HPDF_FONTDEF_TYPE_TYPE3RASTER) { HPDF_SetError(mmgr->error, HPDF_INVALID_FONTDEF_TYPE, 0); return NULL; } font = HPDF_Dict_New(mmgr); if (!font) return NULL; font->header.obj_class |= HPDF_OSUBCLASS_FONT; attr = HPDF_GetMem(mmgr, sizeof(HPDF_FontAttr_Rec)); if (!attr) { HPDF_Dict_Free(font); return NULL; } font->header.obj_class |= HPDF_OSUBCLASS_FONT; font->write_fn = Type3RasterFont_OnWrite; font->free_fn = Type3RasterFont_OnFree; HPDF_MemSet(attr, 0, sizeof(HPDF_FontAttr_Rec)); font->attr = attr; attr->type = HPDF_FONT_TYPE3; attr->writing_mode = HPDF_WMODE_HORIZONTAL; attr->text_width_fn = Type3RasterFont_TextWidth; attr->measure_text_fn = Type3RasterFont_MeasureText; attr->fontdef = fontdef; attr->encoder = encoder; attr->xref = xref; /* singlebyte-font has a widths-array which is an array of 256 signed * short integer. */ attr->widths = HPDF_GetMem(mmgr, sizeof(HPDF_INT16) * 256); if (!attr->widths) { HPDF_Dict_Free(font); return NULL; } encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr; HPDF_MemSet(attr->widths, 0, sizeof(HPDF_INT16) * 256); for (i = 0 /*encoder_attr->first_char*/; i <= 255 /*encoder_attr->last_char*/; i++) { HPDF_UINT16 w = HPDF_Type3RasterFontDef_GetWidth(fontdef, i); attr->widths[i] = w; } fontdef_attr = (HPDF_Type3RasterFontDefAttr)fontdef->attr; ret += HPDF_Dict_AddName(font, "Name", fontdef->base_font); ret += HPDF_Dict_AddName(font, "Type", "Font"); ret += HPDF_Dict_AddName(font, "Subtype", "Type3"); HPDF_REAL scale_x = 72.0f / (HPDF_REAL)fontdef_attr->dpi_x; HPDF_REAL scale_y = 72.0f / (HPDF_REAL)fontdef_attr->dpi_y; HPDF_TransMatrix font_matrix; font_matrix.a = scale_x; font_matrix.b = 0; font_matrix.c = 0; font_matrix.d = scale_y; font_matrix.x = 0; font_matrix.y = 0; HPDF_Array array = HPDF_Array_New(mmgr); ret += HPDF_Array_AddReal(array, font_matrix.a); ret += HPDF_Array_AddReal(array, font_matrix.b); ret += HPDF_Array_AddReal(array, font_matrix.c); ret += HPDF_Array_AddReal(array, font_matrix.d); ret += HPDF_Array_AddReal(array, font_matrix.x); ret += HPDF_Array_AddReal(array, font_matrix.y); ret += HPDF_Dict_Add(font, "FontMatrix", array); HPDF_Array diff_array = HPDF_Array_New(mmgr); ret += HPDF_Array_AddNumber(diff_array, 0); for (i = 0; i < 256; ++i) { char name[3]; sprintf(name, "%02X", i); ret += HPDF_Array_AddName(diff_array, name); } HPDF_Dict encoding = HPDF_Dict_New(mmgr); ret += HPDF_Dict_Add(encoding, "Differences", diff_array); ret += HPDF_Dict_Add(font, "Encoding", encoding); HPDF_Dict char_procs = HPDF_Dict_New(mmgr); for (i = 0; i < 256; ++i) { char name[3]; sprintf(name, "%02X", i); HPDF_Dict char_stream_dict = HPDF_DictStream_New(mmgr, xref); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].width / scale_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " 0 "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].left / scale_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].bottom / scale_y); HPDF_Stream_WriteStr(char_stream_dict->stream, " "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].right / scale_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].top / scale_y); HPDF_Stream_WriteStr(char_stream_dict->stream, " d1\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "q\012"); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].pixels_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " 0 0 "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].pixels_y); HPDF_Stream_WriteStr(char_stream_dict->stream, " "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].left / scale_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " "); HPDF_Stream_WriteReal(char_stream_dict->stream, fontdef_attr->chars[i].bottom / scale_y); HPDF_Stream_WriteStr(char_stream_dict->stream, " cm\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "BI\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "/IM true\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "/W "); HPDF_Stream_WriteInt(char_stream_dict->stream, fontdef_attr->chars[i].pixels_x); HPDF_Stream_WriteStr(char_stream_dict->stream, " /H "); HPDF_Stream_WriteInt(char_stream_dict->stream, fontdef_attr->chars[i].pixels_y); HPDF_Stream_WriteStr(char_stream_dict->stream, "\012/BPC 1\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "/D [1 0]\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "ID\012"); if (fontdef_attr->chars[i].raster_data != NULL) HPDF_Stream_Write(char_stream_dict->stream, fontdef_attr->chars[i].raster_data, fontdef_attr->chars[i].raster_data_size); HPDF_Stream_WriteStr(char_stream_dict->stream, "\012EI\012"); HPDF_Stream_WriteStr(char_stream_dict->stream, "Q"); ret += HPDF_Dict_Add(char_procs, name, char_stream_dict); if (fontdef_attr->chars[i].left < fontdef->font_bbox.left) fontdef->font_bbox.left = fontdef_attr->chars[i].left; if (fontdef_attr->chars[i].bottom < fontdef->font_bbox.bottom) fontdef->font_bbox.bottom = fontdef_attr->chars[i].bottom; if (fontdef_attr->chars[i].right > fontdef->font_bbox.right) fontdef->font_bbox.right = fontdef_attr->chars[i].right; if (fontdef_attr->chars[i].top > fontdef->font_bbox.top) fontdef->font_bbox.top = fontdef_attr->chars[i].top; } fontdef->font_bbox.left /= scale_x; fontdef->font_bbox.bottom /= scale_y; fontdef->font_bbox.right /= scale_x; fontdef->font_bbox.top /= scale_y; ret += HPDF_Dict_Add(font, "CharProcs", char_procs); array = HPDF_Box_Array_New(mmgr, fontdef->font_bbox); ret += HPDF_Dict_Add(font, "FontBBox", array); if (ret != HPDF_OK) { HPDF_Dict_Free(font); return NULL; } if (HPDF_Xref_Add(xref, font) != HPDF_OK) return NULL; return font; }
HPDF_Font HPDF_TTFont_New (HPDF_MMgr mmgr, HPDF_FontDef fontdef, HPDF_Encoder encoder, HPDF_Xref xref) { HPDF_Dict font; HPDF_FontAttr attr; HPDF_TTFontDefAttr fontdef_attr; HPDF_BasicEncoderAttr encoder_attr; HPDF_STATUS ret = 0; HPDF_PTRACE ((" HPDF_TTFont_New\n")); font = HPDF_Dict_New (mmgr); if (!font) return NULL; font->header.obj_class |= HPDF_OSUBCLASS_FONT; /* check whether the fontdef object and the encoder object is valid. */ if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) { HPDF_SetError(font->error, HPDF_INVALID_ENCODER_TYPE, 0); return NULL; } if (fontdef->type != HPDF_FONTDEF_TYPE_TRUETYPE) { HPDF_SetError(font->error, HPDF_INVALID_FONTDEF_TYPE, 0); return NULL; } attr = (HPDF_FontAttr)HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec)); if (!attr) { HPDF_Dict_Free (font); return NULL; } HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec)); font->header.obj_class |= HPDF_OSUBCLASS_FONT; font->write_fn = OnWrite; font->before_write_fn = BeforeWrite; font->free_fn = OnFree; font->attr = attr; attr->type = HPDF_FONT_TRUETYPE; attr->writing_mode = HPDF_WMODE_HORIZONTAL; attr->text_width_fn = TextWidth; attr->measure_text_fn = MeasureText; attr->fontdef = fontdef; attr->encoder = encoder; attr->xref = xref; /* singlebyte-font has a widths-array which is an array of 256 signed * short integer. * in the case of type1-font, widths-array for all letters is made in * constructer. but in the case of true-type-font, the array is * initialized at 0, and set when the corresponding character was used * for the first time. */ attr->widths = (HPDF_INT16*)HPDF_GetMem (mmgr, sizeof(HPDF_INT16) * 256); if (!attr->widths) { HPDF_Dict_Free (font); return NULL; } HPDF_MemSet (attr->widths, 0, sizeof(HPDF_INT16) * 256); attr->used = (HPDF_BYTE*)HPDF_GetMem (mmgr, sizeof(HPDF_BYTE) * 256); if (!attr->used) { HPDF_Dict_Free (font); return NULL; } HPDF_MemSet (attr->used, 0, sizeof(HPDF_BYTE) * 256); fontdef_attr = (HPDF_TTFontDefAttr)fontdef->attr; ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef_attr->base_font); ret += HPDF_Dict_AddName (font, "Subtype", "TrueType"); encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr; ret += HPDF_Dict_AddNumber (font, "FirstChar", encoder_attr->first_char); ret += HPDF_Dict_AddNumber (font, "LastChar", encoder_attr->last_char); if (fontdef->missing_width != 0) ret += HPDF_Dict_AddNumber (font, "MissingWidth", fontdef->missing_width); if (ret != HPDF_OK) { HPDF_Dict_Free (font); return NULL; } if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; return font; }
HPDF_Font HPDF_Type0Font_New (HPDF_MMgr mmgr, HPDF_FontDef fontdef, HPDF_Encoder encoder, HPDF_Xref xref) { HPDF_Dict font; HPDF_FontAttr attr; HPDF_CMapEncoderAttr encoder_attr; HPDF_STATUS ret = 0; HPDF_Array descendant_fonts; HPDF_PTRACE ((" HPDF_Type0Font_New\n")); font = HPDF_Dict_New (mmgr); if (!font) return NULL; font->header.obj_class |= HPDF_OSUBCLASS_FONT; /* check whether the fontdef object and the encoder object is valid. */ if (encoder->type != HPDF_ENCODER_TYPE_DOUBLE_BYTE) { HPDF_SetError(font->error, HPDF_INVALID_ENCODER_TYPE, 0); return NULL; } if (fontdef->type != HPDF_FONTDEF_TYPE_CID && fontdef->type != HPDF_FONTDEF_TYPE_TRUETYPE) { HPDF_SetError(font->error, HPDF_INVALID_FONTDEF_TYPE, 0); return NULL; } attr = HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec)); if (!attr) { HPDF_Dict_Free (font); return NULL; } font->header.obj_class |= HPDF_OSUBCLASS_FONT; font->write_fn = NULL; font->free_fn = OnFree_Func; font->attr = attr; encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec)); attr->writing_mode = encoder_attr->writing_mode; attr->text_width_fn = TextWidth; attr->measure_text_fn = MeasureText; attr->fontdef = fontdef; attr->encoder = encoder; attr->xref = xref; if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font); ret += HPDF_Dict_AddName (font, "Subtype", "Type0"); if (fontdef->type == HPDF_FONTDEF_TYPE_CID) { ret += HPDF_Dict_AddName (font, "Encoding", encoder->name); } else { attr->cmap_stream = CreateCMap (encoder, xref); if (attr->cmap_stream) { ret += HPDF_Dict_Add (font, "Encoding", attr->cmap_stream); } else return NULL; } if (ret != HPDF_OK) return NULL; descendant_fonts = HPDF_Array_New (mmgr); if (!descendant_fonts) return NULL; if (HPDF_Dict_Add (font, "DescendantFonts", descendant_fonts) != HPDF_OK) return NULL; if (fontdef->type == HPDF_FONTDEF_TYPE_CID) { attr->descendant_font = CIDFontType0_New (font, xref); attr->type = HPDF_FONT_TYPE0_CID; } else { attr->descendant_font = CIDFontType2_New (font, xref); attr->type = HPDF_FONT_TYPE0_TT; } if (!attr->descendant_font) return NULL; else if (HPDF_Array_Add (descendant_fonts, attr->descendant_font) != HPDF_OK) return NULL; return font; }
static HPDF_Font CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref) { HPDF_STATUS ret = HPDF_OK; HPDF_FontAttr attr = (HPDF_FontAttr)parent->attr; HPDF_FontDef fontdef = attr->fontdef; HPDF_TTFontDefAttr fontdef_attr = (HPDF_TTFontDefAttr)fontdef->attr; HPDF_Encoder encoder = attr->encoder; HPDF_CMapEncoderAttr encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_Font font; HPDF_Array array; HPDF_UINT i; HPDF_UNICODE tmp_map[65536]; HPDF_Dict cid_system_info; HPDF_UINT16 max = 0; HPDF_PTRACE ((" HPDF_CIDFontType2_New\n")); font = HPDF_Dict_New (parent->mmgr); if (!font) return NULL; if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; parent->before_write_fn = CIDFontType2_BeforeWrite_Func; ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "Subtype", "CIDFontType2"); ret += HPDF_Dict_AddNumber (font, "DW", fontdef->missing_width); if (ret != HPDF_OK) return NULL; /* add 'DW2' element */ array = HPDF_Array_New (font->mmgr); if (!array) return NULL; if (HPDF_Dict_Add (font, "DW2", array) != HPDF_OK) return NULL; ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.bottom)); ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.bottom - fontdef->font_bbox.top)); HPDF_MemSet (tmp_map, 0, sizeof(HPDF_UNICODE) * 65536); if (ret != HPDF_OK) return NULL; for (i = 0; i < 256; i++) { HPDF_UINT j; for (j = 0; j < 256; j++) { if (encoder->to_unicode_fn == HPDF_CMapEncoder_ToUnicode) { HPDF_UINT16 cid = encoder_attr->cid_map[i][j]; if (cid != 0) { HPDF_UNICODE unicode = encoder_attr->unicode_map[i][j]; HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, unicode); tmp_map[cid] = gid; if (max < cid) max = cid; } } else { HPDF_UNICODE unicode = (i << 8) | j; HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, unicode); tmp_map[unicode] = gid; if (max < unicode) max = unicode; } } } if (max > 0) { HPDF_INT16 dw = fontdef->missing_width; HPDF_UNICODE *ptmp_map = tmp_map; HPDF_Array tmp_array = NULL; /* add 'W' element */ array = HPDF_Array_New (font->mmgr); if (!array) return NULL; if (HPDF_Dict_Add (font, "W", array) != HPDF_OK) return NULL; for (i = 0; i < max; i++, ptmp_map++) { HPDF_INT w = HPDF_TTFontDef_GetGidWidth (fontdef, *ptmp_map); if (w != dw) { if (!tmp_array) { if (HPDF_Array_AddNumber (array, i) != HPDF_OK) return NULL; tmp_array = HPDF_Array_New (font->mmgr); if (!tmp_array) return NULL; if (HPDF_Array_Add (array, tmp_array) != HPDF_OK) return NULL; } if ((ret = HPDF_Array_AddNumber (tmp_array, w)) != HPDF_OK) return NULL; } else tmp_array = NULL; } /* create "CIDToGIDMap" data */ if (fontdef_attr->embedding) { attr->map_stream = HPDF_DictStream_New (font->mmgr, xref); if (!attr->map_stream) return NULL; if (HPDF_Dict_Add (font, "CIDToGIDMap", attr->map_stream) != HPDF_OK) return NULL; for (i = 0; i < max; i++) { HPDF_BYTE u[2]; HPDF_UINT16 gid = tmp_map[i]; u[0] = (HPDF_BYTE)(gid >> 8); u[1] = (HPDF_BYTE)gid; HPDF_MemCpy ((HPDF_BYTE *)(tmp_map + i), u, 2); } if ((ret = HPDF_Stream_Write (attr->map_stream->stream, (HPDF_BYTE *)tmp_map, max * 2)) != HPDF_OK) return NULL; }
HPDF_Font HPDF_Type0Font_New (HPDF_MMgr mmgr, HPDF_FontDef fontdef, HPDF_Encoder encoder, HPDF_Xref xref) { HPDF_Dict font; HPDF_FontAttr attr; HPDF_CMapEncoderAttr encoder_attr; HPDF_STATUS ret = 0; HPDF_Array descendant_fonts; HPDF_PTRACE ((" HPDF_Type0Font_New\n")); font = HPDF_Dict_New (mmgr); if (!font) return NULL; font->header.obj_class |= HPDF_OSUBCLASS_FONT; /* check whether the fontdef object and the encoder object is valid. */ if (encoder->type != HPDF_ENCODER_TYPE_DOUBLE_BYTE) { HPDF_SetError(font->error, HPDF_INVALID_ENCODER_TYPE, 0); return NULL; } if (fontdef->type != HPDF_FONTDEF_TYPE_CID && fontdef->type != HPDF_FONTDEF_TYPE_TRUETYPE) { HPDF_SetError(font->error, HPDF_INVALID_FONTDEF_TYPE, 0); return NULL; } attr = HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec)); if (!attr) { HPDF_Dict_Free (font); return NULL; } font->header.obj_class |= HPDF_OSUBCLASS_FONT; font->write_fn = NULL; font->free_fn = OnFree_Func; font->attr = attr; encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec)); attr->writing_mode = encoder_attr->writing_mode; attr->text_width_fn = TextWidth; attr->measure_text_fn = MeasureText; attr->fontdef = fontdef; attr->encoder = encoder; attr->xref = xref; if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font); ret += HPDF_Dict_AddName (font, "Subtype", "Type0"); if (fontdef->type == HPDF_FONTDEF_TYPE_CID) { ret += HPDF_Dict_AddName (font, "Encoding", encoder->name); } else { /* * Handle the Unicode encoding, see hpdf_encoding_utf.c For some * reason, xpdf-based readers cannot deal with our cmap but work * fine when using the predefined "Identity-H" * encoding. However, text selection does not work, unless we * add a ToUnicode cmap. This CMap should also be "Identity", * but that does not work -- specifying our cmap as a stream however * does work. Who can understand that ? */ if (HPDF_StrCmp(encoder_attr->ordering, "Identity-H") == 0) { ret += HPDF_Dict_AddName (font, "Encoding", "Identity-H"); attr->cmap_stream = CreateCMap (encoder, xref); if (attr->cmap_stream) { ret += HPDF_Dict_Add (font, "ToUnicode", attr->cmap_stream); } else return NULL; } else { attr->cmap_stream = CreateCMap (encoder, xref); if (attr->cmap_stream) { ret += HPDF_Dict_Add (font, "Encoding", attr->cmap_stream); } else return NULL; } } if (ret != HPDF_OK) return NULL; descendant_fonts = HPDF_Array_New (mmgr); if (!descendant_fonts) return NULL; if (HPDF_Dict_Add (font, "DescendantFonts", descendant_fonts) != HPDF_OK) return NULL; if (fontdef->type == HPDF_FONTDEF_TYPE_CID) { attr->descendant_font = CIDFontType0_New (font, xref); attr->type = HPDF_FONT_TYPE0_CID; } else { attr->descendant_font = CIDFontType2_New (font, xref); attr->type = HPDF_FONT_TYPE0_TT; } if (!attr->descendant_font) return NULL; else if (HPDF_Array_Add (descendant_fonts, attr->descendant_font) != HPDF_OK) return NULL; return font; }
HPDF_Font HPDF_Type1Font_New (HPDF_MMgr mmgr, HPDF_FontDef fontdef, HPDF_Encoder encoder, HPDF_Xref xref) { HPDF_Dict font; HPDF_FontAttr attr; HPDF_Type1FontDefAttr fontdef_attr; HPDF_BasicEncoderAttr encoder_attr; HPDF_STATUS ret = 0; HPDF_UINT i; HPDF_PTRACE ((" HPDF_Type1Font_New\n")); /* check whether the fontdef object and the encoder object is valid. */ if (encoder->type != HPDF_ENCODER_TYPE_SINGLE_BYTE) { HPDF_SetError(mmgr->error, HPDF_INVALID_ENCODER_TYPE, 0); return NULL; } if (fontdef->type != HPDF_FONTDEF_TYPE_TYPE1) { HPDF_SetError(mmgr->error, HPDF_INVALID_FONTDEF_TYPE, 0); return NULL; } font = HPDF_Dict_New (mmgr); if (!font) return NULL; font->header.obj_class |= HPDF_OSUBCLASS_FONT; attr = HPDF_GetMem (mmgr, sizeof(HPDF_FontAttr_Rec)); if (!attr) { HPDF_Dict_Free (font); return NULL; } font->header.obj_class |= HPDF_OSUBCLASS_FONT; font->write_fn = Type1Font_OnWrite; font->free_fn = Type1Font_OnFree; HPDF_MemSet (attr, 0, sizeof(HPDF_FontAttr_Rec)); font->attr = attr; attr->type = HPDF_FONT_TYPE1; attr->writing_mode = HPDF_WMODE_HORIZONTAL; attr->text_width_fn = Type1Font_TextWidth; attr->measure_text_fn = Type1Font_MeasureText; attr->fontdef = fontdef; attr->encoder = encoder; attr->xref = xref; /* singlebyte-font has a widths-array which is an array of 256 signed * short integer. */ attr->widths = HPDF_GetMem (mmgr, sizeof(HPDF_INT16) * 256); if (!attr->widths) { HPDF_Dict_Free (font); return NULL; } encoder_attr = (HPDF_BasicEncoderAttr)encoder->attr; HPDF_MemSet (attr->widths, 0, sizeof(HPDF_INT16) * 256); for (i = encoder_attr->first_char; i <= encoder_attr->last_char; i++) { HPDF_UNICODE u = encoder_attr->unicode_map[i]; HPDF_UINT16 w = HPDF_Type1FontDef_GetWidth (fontdef, u); attr->widths[i] = w; } fontdef_attr = (HPDF_Type1FontDefAttr)fontdef->attr; if(strncmp (fontdef->base_font, "HPDF_", 5) == 0 && fontdef->is_form_font == HPDF_TRUE) { ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font + 5); ret += HPDF_Dict_AddName (font, "Subtype", "TrueType"); } else{ ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font); ret += HPDF_Dict_AddName (font, "Subtype", "Type1"); } if (!fontdef_attr->is_base14font) { if (fontdef->missing_width != 0) ret += HPDF_Dict_AddNumber (font, "MissingWidth", fontdef->missing_width); ret += Type1Font_CreateDescriptor (mmgr, font, xref); } if (ret != HPDF_OK) { HPDF_Dict_Free (font); return NULL; } if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; return font; }