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; }
static HPDF_STATUS ReadTransparentPaletteData (HPDF_Dict image, png_structp png_ptr, png_infop info_ptr, png_bytep smask_data, png_bytep trans, int num_trans) { HPDF_STATUS ret = HPDF_OK; HPDF_UINT i, j; png_bytep *row_ptr; png_uint_32 height = png_get_image_height(png_ptr, info_ptr); png_uint_32 width = png_get_image_width(png_ptr, info_ptr); row_ptr = HPDF_GetMem (image->mmgr, height * sizeof(png_bytep)); if (!row_ptr) { return HPDF_FAILD_TO_ALLOC_MEM; } else { png_uint_32 len = png_get_rowbytes(png_ptr, info_ptr); for (i = 0; i < (HPDF_UINT)height; i++) { row_ptr[i] = HPDF_GetMem(image->mmgr, len); if (!row_ptr[i]) { for (; i > 0; i--) { HPDF_FreeMem (image->mmgr, row_ptr[i]); } HPDF_FreeMem (image->mmgr, row_ptr); return HPDF_FAILD_TO_ALLOC_MEM; } } } png_read_image(png_ptr, row_ptr); if (image->error->error_no != HPDF_OK) { ret = HPDF_INVALID_PNG_IMAGE; goto Error; } for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { smask_data[width * j + i] = (row_ptr[j][i] < num_trans) ? trans[row_ptr[j][i]] : 0xFF; } if (HPDF_Stream_Write (image->stream, row_ptr[j], width) != HPDF_OK) { ret = HPDF_FILE_IO_ERROR; goto Error; } } Error: for (i = 0; i < (HPDF_UINT)height; i++) { HPDF_FreeMem (image->mmgr, row_ptr[i]); } HPDF_FreeMem (image->mmgr, row_ptr); return ret; }
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_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; }
static HPDF_STATUS ReadPngData (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 buf_ptr = HPDF_GetMem (image->mmgr, len); if (buf_ptr) { HPDF_UINT i; for (i = 0; i < (HPDF_UINT)height; i++) { png_read_rows(png_ptr, (png_byte**)&buf_ptr, NULL, 1); if (image->error->error_no != HPDF_OK) break; if (HPDF_Stream_Write (image->stream, buf_ptr, len) != HPDF_OK) break; } HPDF_FreeMem (image->mmgr, buf_ptr); } return image->error->error_no; }
static HPDF_STATUS Resize (HPDF_List list, HPDF_UINT count) { void **new_obj; HPDF_PTRACE((" HPDF_List_Resize\n")); if (list->count >= count) { if (list->count == count) return HPDF_OK; else return HPDF_INVALID_PARAMETER; } new_obj = (void **)HPDF_GetMem (list->mmgr, count * sizeof(void *)); if (!new_obj) return HPDF_Error_GetCode (list->error); if (list->obj) HPDF_MemCpy ((HPDF_BYTE *)new_obj, (HPDF_BYTE *)list->obj, list->block_siz * sizeof(void *)); list->block_siz = count; if (list->obj) HPDF_FreeMem (list->mmgr, list->obj); list->obj = new_obj; return HPDF_OK; }
HPDF_EncryptDict HPDF_EncryptDict_New (HPDF_MMgr mmgr, HPDF_Xref xref) { HPDF_Encrypt attr; HPDF_EncryptDict dict; HPDF_PTRACE((" HPDF_EncryptDict_New\n")); dict = HPDF_Dict_New (mmgr); if (!dict) return NULL; dict->header.obj_class |= HPDF_OSUBCLASS_ENCRYPT; dict->free_fn = HPDF_EncryptDict_OnFree; attr = HPDF_GetMem (dict->mmgr, sizeof(HPDF_Encrypt_Rec)); if (!attr) { HPDF_Dict_Free (dict); return NULL; } dict->attr = attr; HPDF_Encrypt_Init (attr); if (HPDF_Xref_Add (xref, dict) != HPDF_OK) return NULL; return dict; }
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_STATUS HPDF_String_SetValue (HPDF_String obj, const char *value) { HPDF_UINT len; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE((" HPDF_String_SetValue\n")); if (obj->value) { HPDF_FreeMem (obj->mmgr, obj->value); obj->len = 0; } len = HPDF_StrLen(value, HPDF_LIMIT_MAX_STRING_LEN + 1); if (len > HPDF_LIMIT_MAX_STRING_LEN) return HPDF_SetError (obj->error, HPDF_STRING_OUT_OF_RANGE, 0); obj->value = HPDF_GetMem (obj->mmgr, len + 1); if (!obj->value) return HPDF_Error_GetCode (obj->error); HPDF_StrCpy ((char *)obj->value, value, (char *)obj->value + len); obj->len = len; return ret; }
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; }
HPDF_STATUS HPDF_CIDFontDef_AddWidth (HPDF_FontDef fontdef, const HPDF_CID_Width *widths) { HPDF_CIDFontDefAttr attr = (HPDF_CIDFontDefAttr)fontdef->attr; HPDF_PTRACE (" HPDF_CIDFontDef_AddWidth\n"); while (widths->cid != 0xFFFF) { HPDF_CID_Width *w = HPDF_GetMem (fontdef->mmgr, sizeof (HPDF_CID_Width)); HPDF_STATUS ret; if (!w) return fontdef->error->error_no; w->cid = widths->cid; w->width = widths->width; if ((ret = HPDF_List_Add (attr->widths, w)) != HPDF_OK) { HPDF_FreeMem (fontdef->mmgr, w); return ret; } widths++; } return HPDF_OK; }
HPDF_STATUS HPDF_Xref_Add (HPDF_Xref xref, void *obj) { HPDF_XrefEntry entry; HPDF_Obj_Header *header; HPDF_PTRACE((" HPDF_Xref_Add\n")); if (!obj) { if (HPDF_Error_GetCode (xref->error) == HPDF_OK) return HPDF_SetError (xref->error, HPDF_INVALID_OBJECT, 0); else return HPDF_INVALID_OBJECT; } header = (HPDF_Obj_Header *)obj; if (header->obj_id & HPDF_OTYPE_DIRECT || header->obj_id & HPDF_OTYPE_INDIRECT) return HPDF_SetError(xref->error, HPDF_INVALID_OBJECT, 0); if (xref->entries->count >= HPDF_LIMIT_MAX_XREF_ELEMENT) { HPDF_SetError(xref->error, HPDF_XREF_COUNT_ERR, 0); goto Fail; } /* in the following, we have to dispose the object when an error is * occured. */ entry = (HPDF_XrefEntry)HPDF_GetMem (xref->mmgr, sizeof(HPDF_XrefEntry_Rec)); if (entry == NULL) goto Fail; if (HPDF_List_Add(xref->entries, entry) != HPDF_OK) { HPDF_FreeMem (xref->mmgr, entry); goto Fail; } entry->entry_typ = HPDF_IN_USE_ENTRY; entry->byte_offset = 0; entry->gen_no = 0; entry->obj = obj; header->obj_id = xref->start_offset + xref->entries->count - 1 + HPDF_OTYPE_INDIRECT; header->gen_no = entry->gen_no; return HPDF_OK; Fail: HPDF_Obj_ForceFree(xref->mmgr, obj); return HPDF_Error_GetCode (xref->error); }
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; }
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_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; }
static HPDF_STATUS CreatePallet (HPDF_Dict image, png_structp png_ptr, png_infop info_ptr) { HPDF_INT num_pl = 0; png_color *src_pl = NULL; HPDF_BYTE *ppallet; HPDF_BYTE *p; HPDF_UINT i; HPDF_Array array; /* png_get_PLTE does not call PngErrorFunc even if it failed. * so we call HPDF_Set_Error to set error-code. */ if (png_get_PLTE(png_ptr, info_ptr, (png_color**)&src_pl, &num_pl) != PNG_INFO_PLTE) return HPDF_SetError (image->error, HPDF_LIBPNG_ERROR, HPDF_CANNOT_GET_PALLET); /* make a pallet array for indexed image. */ ppallet = HPDF_GetMem (image->mmgr, num_pl * 3); if (!ppallet) return image->error->error_no; p = ppallet; for (i = 0; i < num_pl; i++, src_pl++) { *p++ = src_pl->red; *p++ = src_pl->green; *p++ = src_pl->blue; } array = HPDF_Array_New (image->mmgr); if (array) { HPDF_Binary b; HPDF_Dict_Add (image, "ColorSpace", array); HPDF_Array_AddName (array, "Indexed"); HPDF_Array_AddName (array, "DeviceRGB"); HPDF_Array_AddNumber (array, num_pl - 1); b = HPDF_Binary_New (image->mmgr, ppallet, num_pl * 3); if (b) HPDF_Array_Add (array, b); } HPDF_FreeMem (image->mmgr, ppallet); return image->error->error_no; }
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_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; }
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; }
HPDF_STATUS HPDF_Binary_SetValue (HPDF_Binary obj, HPDF_BYTE *value, HPDF_UINT len) { if (len > HPDF_LIMIT_MAX_STRING_LEN) return HPDF_SetError (obj->error, HPDF_BINARY_LENGTH_ERR, 0); if (obj->value) { HPDF_FreeMem (obj->mmgr, obj->value); obj->len = 0; } obj->value = HPDF_GetMem (obj->mmgr, len); if (!obj->value) return HPDF_Error_GetCode (obj->error); HPDF_MemCpy (obj->value, value, len); obj->len = len; return HPDF_OK; }
HPDF_List HPDF_List_New (HPDF_MMgr mmgr, HPDF_UINT items_per_block) { HPDF_List list; HPDF_PTRACE((" HPDF_List_New\n")); if (mmgr == NULL) return NULL; list = (HPDF_List)HPDF_GetMem (mmgr, sizeof(HPDF_List_Rec)); if (list) { list->mmgr = mmgr; list->error = mmgr->error; list->block_siz = 0; list->items_per_block = (items_per_block <= 0 ? HPDF_DEF_ITEMS_PER_BLOCK : items_per_block); list->count = 0; list->obj = NULL; } return list; }
static HPDF_STATUS LoadPngData (HPDF_Dict image, HPDF_Xref xref, HPDF_Stream png_data, HPDF_BOOL delayed_loading) { HPDF_STATUS ret = HPDF_OK; png_uint_32 width, height; int bit_depth, color_type; png_structp png_ptr = NULL; png_infop info_ptr = NULL; HPDF_PTRACE ((" HPDF_Image_LoadPngImage\n")); /* create read_struct. */ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, image->error, PngErrorFunc, PngErrorFunc); if (png_ptr == NULL) { HPDF_SetError (image->error, HPDF_FAILD_TO_ALLOC_MEM, 0); return HPDF_FAILD_TO_ALLOC_MEM; } /* create info-struct */ info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL) { HPDF_SetError (image->error, HPDF_FAILD_TO_ALLOC_MEM, 0); goto Exit; } png_set_sig_bytes (png_ptr, HPDF_PNG_BYTES_TO_CHECK); png_set_read_fn (png_ptr, (void *)png_data, (png_rw_ptr)&PngReadFunc); /* reading info structure. */ png_read_info(png_ptr, info_ptr); if (image->error->error_no != HPDF_OK) { goto Exit; } png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); /* 16bit images are not supported. */ if (bit_depth == 16) { png_set_strip_16(png_ptr); } png_read_update_info(png_ptr, info_ptr); if (image->error->error_no != HPDF_OK) { goto Exit; } /* check palette-based images for transparent areas and load them immediately if found */ if (xref && PNG_COLOR_TYPE_PALETTE & color_type) { png_bytep trans; int num_trans; HPDF_Dict smask; png_bytep smask_data; if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) || !png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL)) { goto no_transparent_color_in_palette; } smask = HPDF_DictStream_New (image->mmgr, xref); if (!smask) { ret = HPDF_FAILD_TO_ALLOC_MEM; goto Exit; } smask->header.obj_class |= HPDF_OSUBCLASS_XOBJECT; ret = HPDF_Dict_AddName (smask, "Type", "XObject"); ret += HPDF_Dict_AddName (smask, "Subtype", "Image"); ret += HPDF_Dict_AddNumber (smask, "Width", (HPDF_UINT)width); ret += HPDF_Dict_AddNumber (smask, "Height", (HPDF_UINT)height); ret += HPDF_Dict_AddName (smask, "ColorSpace", "DeviceGray"); ret += HPDF_Dict_AddNumber (smask, "BitsPerComponent", (HPDF_UINT)bit_depth); if (ret != HPDF_OK) { HPDF_Dict_Free(smask); ret = HPDF_INVALID_PNG_IMAGE; goto Exit; } smask_data = HPDF_GetMem(image->mmgr, width * height); if (!smask_data) { HPDF_Dict_Free(smask); ret = HPDF_FAILD_TO_ALLOC_MEM; goto Exit; } if (ReadTransparentPaletteData(image, png_ptr, info_ptr, smask_data, trans, num_trans) != HPDF_OK) { HPDF_FreeMem(image->mmgr, smask_data); HPDF_Dict_Free(smask); ret = HPDF_INVALID_PNG_IMAGE; goto Exit; } if (HPDF_Stream_Write(smask->stream, smask_data, width * height) != HPDF_OK) { HPDF_FreeMem(image->mmgr, smask_data); HPDF_Dict_Free(smask); ret = HPDF_FILE_IO_ERROR; goto Exit; } HPDF_FreeMem(image->mmgr, smask_data); ret += CreatePallet(image, png_ptr, info_ptr); ret += HPDF_Dict_AddNumber (image, "Width", (HPDF_UINT)width); ret += HPDF_Dict_AddNumber (image, "Height", (HPDF_UINT)height); ret += HPDF_Dict_AddNumber (image, "BitsPerComponent", (HPDF_UINT)bit_depth); ret += HPDF_Dict_Add (image, "SMask", smask); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return HPDF_OK; } no_transparent_color_in_palette: /* read images with alpha channel right away we have to do this because image transparent mask must be added to the Xref */ if (xref && PNG_COLOR_MASK_ALPHA & color_type) { HPDF_Dict smask; png_bytep smask_data; smask = HPDF_DictStream_New (image->mmgr, xref); if (!smask) { ret = HPDF_FAILD_TO_ALLOC_MEM; goto Exit; } smask->header.obj_class |= HPDF_OSUBCLASS_XOBJECT; ret = HPDF_Dict_AddName (smask, "Type", "XObject"); ret += HPDF_Dict_AddName (smask, "Subtype", "Image"); ret += HPDF_Dict_AddNumber (smask, "Width", (HPDF_UINT)width); ret += HPDF_Dict_AddNumber (smask, "Height", (HPDF_UINT)height); ret += HPDF_Dict_AddName (smask, "ColorSpace", "DeviceGray"); ret += HPDF_Dict_AddNumber (smask, "BitsPerComponent", (HPDF_UINT)bit_depth); if (ret != HPDF_OK) { HPDF_Dict_Free(smask); ret = HPDF_INVALID_PNG_IMAGE; goto Exit; } smask_data = HPDF_GetMem(image->mmgr, width * height); if (!smask_data) { HPDF_Dict_Free(smask); ret = HPDF_FAILD_TO_ALLOC_MEM; goto Exit; } if (ReadTransparentPngData(image, png_ptr, info_ptr, smask_data) != HPDF_OK) { HPDF_FreeMem(image->mmgr, smask_data); HPDF_Dict_Free(smask); ret = HPDF_INVALID_PNG_IMAGE; goto Exit; } if (HPDF_Stream_Write(smask->stream, smask_data, width * height) != HPDF_OK) { HPDF_FreeMem(image->mmgr, smask_data); HPDF_Dict_Free(smask); ret = HPDF_FILE_IO_ERROR; goto Exit; } HPDF_FreeMem(image->mmgr, smask_data); if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { ret += HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray"); } else { ret += HPDF_Dict_AddName (image, "ColorSpace", "DeviceRGB"); } ret += HPDF_Dict_AddNumber (image, "Width", (HPDF_UINT)width); ret += HPDF_Dict_AddNumber (image, "Height", (HPDF_UINT)height); ret += HPDF_Dict_AddNumber (image, "BitsPerComponent", (HPDF_UINT)bit_depth); ret += HPDF_Dict_Add (image, "SMask", smask); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return HPDF_OK; } /* if the image has color palette, copy the pallet of the image to * create color map. */ if (color_type == PNG_COLOR_TYPE_PALETTE) ret = CreatePallet(image, png_ptr, info_ptr); else if (color_type == PNG_COLOR_TYPE_GRAY) ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray"); else ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceRGB"); if (ret != HPDF_OK) goto Exit; /* read image-data * if the image is interlaced, read whole image at once. * if delayed_loading is HPDF_TRUE, the data does not load this phase. */ if (delayed_loading) { image->before_write_fn = PngBeforeWrite; image->after_write_fn = PngAfterWrite; } else { if (png_get_interlace_type(png_ptr, info_ptr) != PNG_INTERLACE_NONE) ret = ReadPngData_Interlaced(image, png_ptr, info_ptr); else ret = ReadPngData(image, png_ptr, info_ptr); if (ret != HPDF_OK) goto Exit; } /* setting the info of the image. */ if (HPDF_Dict_AddNumber (image, "Width", (HPDF_UINT)width) != HPDF_OK) goto Exit; if (HPDF_Dict_AddNumber (image, "Height", (HPDF_UINT)height) != HPDF_OK) goto Exit; if (HPDF_Dict_AddNumber (image, "BitsPerComponent", (HPDF_UINT)bit_depth) != HPDF_OK) goto Exit; /* clean up */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return HPDF_OK; Exit: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (ret != HPDF_OK) { return ret; } return image->error->error_no; }
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_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; }
static HPDF_STATUS ReadTransparentPngData (HPDF_Dict image, png_structp png_ptr, png_infop info_ptr, png_bytep smask_data) { HPDF_STATUS ret = HPDF_OK; HPDF_INT row_len; HPDF_UINT i, j; png_bytep *row_ptr, row = 0; png_byte color_type; png_uint_32 height = png_get_image_height(png_ptr, info_ptr); png_uint_32 width = png_get_image_width(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); if (!(color_type & PNG_COLOR_MASK_ALPHA)) { return HPDF_INVALID_PNG_IMAGE; } row_ptr = HPDF_GetMem (image->mmgr, height * sizeof(png_bytep)); if (!row_ptr) { return HPDF_FAILD_TO_ALLOC_MEM; } else { png_uint_32 len = png_get_rowbytes(png_ptr, info_ptr); for (i = 0; i < (HPDF_UINT)height; i++) { row_ptr[i] = HPDF_GetMem(image->mmgr, len); if (!row_ptr[i]) { for (; i > 0; i--) { HPDF_FreeMem (image->mmgr, row_ptr[i]); } HPDF_FreeMem (image->mmgr, row_ptr); return HPDF_FAILD_TO_ALLOC_MEM; } } } png_read_image(png_ptr, row_ptr); if (image->error->error_no != HPDF_OK) { ret = HPDF_INVALID_PNG_IMAGE; goto Error; } switch (color_type) { case PNG_COLOR_TYPE_RGB_ALPHA: row_len = 3 * width * sizeof(png_byte); for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { row = row_ptr[j]; memmove(row + (3 * i), row + (4*i), 3); smask_data[width * j + i] = row[4 * i + 3]; } if (HPDF_Stream_Write (image->stream, row, row_len) != HPDF_OK) { ret = HPDF_FILE_IO_ERROR; goto Error; } } break; case PNG_COLOR_TYPE_GRAY_ALPHA: row_len = width * sizeof(png_byte); for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { row = row_ptr[j]; row[i] = row[2 * i]; smask_data[width * j + i] = row[2 * i + 1]; } if (HPDF_Stream_Write (image->stream, row, row_len) != HPDF_OK) { ret = HPDF_FILE_IO_ERROR; goto Error; } } break; default: ret = HPDF_INVALID_PNG_IMAGE; goto Error; } Error: for (i = 0; i < (HPDF_UINT)height; i++) { HPDF_FreeMem (image->mmgr, row_ptr[i]); } HPDF_FreeMem (image->mmgr, row_ptr); return ret; }
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; }
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; }