HPDF_Array HPDF_Box_Array_New (HPDF_MMgr mmgr, HPDF_Box box) { HPDF_Array obj; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE((" HPDF_Box_Array_New\n")); obj = HPDF_Array_New (mmgr); if (!obj) return NULL; ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.left)); ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.bottom)); ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.right)); ret += HPDF_Array_Add (obj, HPDF_Real_New (mmgr, box.top)); if (ret != HPDF_OK) { HPDF_Array_Free (obj); return NULL; } return obj; }
HPDF_STATUS AddResource (HPDF_Page page) { HPDF_STATUS ret = HPDF_OK; HPDF_Dict resource; HPDF_Array procset; HPDF_PTRACE((" HPDF_Page_AddResource\n")); resource = HPDF_Dict_New (page->mmgr); if (!resource) return HPDF_Error_GetCode (page->error); /* althoth ProcSet-entry is obsolete, add it to resouce for * compatibility */ ret += HPDF_Dict_Add (page, "Resources", resource); procset = HPDF_Array_New (page->mmgr); if (!procset) return HPDF_Error_GetCode (page->error); ret += HPDF_Dict_Add (resource, "ProcSet", procset); ret += HPDF_Array_Add (procset, HPDF_Name_New (page->mmgr, "PDF")); ret += HPDF_Array_Add (procset, HPDF_Name_New (page->mmgr, "Text")); ret += HPDF_Array_Add (procset, HPDF_Name_New (page->mmgr, "ImageB")); ret += HPDF_Array_Add (procset, HPDF_Name_New (page->mmgr, "ImageC")); ret += HPDF_Array_Add (procset, HPDF_Name_New (page->mmgr, "ImageI")); return ret; }
/* Generate an ID for the trailer dict, PDF/A needs this. TODO: Better algorithm for generate unique ID. */ HPDF_STATUS HPDF_PDFA_GenerateID(HPDF_Doc pdf) { HPDF_Array id; HPDF_BYTE *currentTime; HPDF_BYTE idkey[HPDF_MD5_KEY_LEN]; HPDF_MD5_CTX md5_ctx; time_t ltime; ltime = time(NULL); currentTime = (HPDF_BYTE *)ctime(<ime); id = HPDF_Dict_GetItem(pdf->trailer, "ID", HPDF_OCLASS_ARRAY); if (!id) { id = HPDF_Array_New(pdf->mmgr); if (!id || HPDF_Dict_Add(pdf->trailer, "ID", id) != HPDF_OK) return pdf->error.error_no; HPDF_MD5Init(&md5_ctx); HPDF_MD5Update(&md5_ctx, (HPDF_BYTE *) "libHaru", sizeof("libHaru") - 1); HPDF_MD5Update(&md5_ctx, currentTime, HPDF_StrLen((const char *)currentTime, -1)); HPDF_MD5Final(idkey, &md5_ctx); if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr, idkey, HPDF_MD5_KEY_LEN)) != HPDF_OK) return pdf->error.error_no; if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr,idkey,HPDF_MD5_KEY_LEN)) != HPDF_OK) return pdf->error.error_no; return HPDF_OK; } return HPDF_OK; }
HPDF_STATUS HPDF_NameTree_Add (HPDF_NameTree tree, HPDF_String name, void *obj) { HPDF_Array items; HPDF_INT32 i, icount; if (!tree || !name) return HPDF_INVALID_PARAMETER; items = HPDF_Dict_GetItem (tree, "Names", HPDF_OCLASS_ARRAY); if (!items) return HPDF_INVALID_OBJECT; /* "The keys shall be sorted in lexical order" -- 7.9.6, Name Trees. * Since we store keys sorted, it's best to do a linear insertion sort * Find the first element larger than 'key', and insert 'key' and then * 'obj' into the items. */ icount = HPDF_Array_Items(items); /* If we're larger than the last element, append */ if (icount) { HPDF_String last = HPDF_Array_GetItem(items, icount - 2, HPDF_OCLASS_STRING); if (HPDF_String_Cmp(name, last) > 0) { HPDF_Array_Add(items, name); HPDF_Array_Add(items, obj); return HPDF_OK; } } /* Walk backwards through the list until we're smaller than an element= * That's the element to insert in front of. */ for (i = icount - 4; i >= 0; i -= 2) { HPDF_String elem = HPDF_Array_GetItem(items, i, HPDF_OCLASS_STRING); if (i == 0 || HPDF_String_Cmp(name, elem) < 0) { HPDF_Array_Insert(items, elem, name); HPDF_Array_Insert(items, elem, obj); return HPDF_OK; } } /* Items list is empty */ HPDF_Array_Add(items, name); HPDF_Array_Add(items, obj); return HPDF_OK; }
HPDF_STATUS HPDF_Pages_AddKids (HPDF_Pages parent, HPDF_Dict kid) { HPDF_Array kids; HPDF_STATUS ret; HPDF_PTRACE((" HPDF_Pages_AddKids\n")); if (HPDF_Dict_GetItem (kid, "Parent", HPDF_OCLASS_DICT)) return HPDF_SetError (parent->error, HPDF_PAGE_CANNOT_SET_PARENT, 0); if ((ret = HPDF_Dict_Add (kid, "Parent", parent)) != HPDF_OK) return ret; kids = (HPDF_Array )HPDF_Dict_GetItem (parent, "Kids", HPDF_OCLASS_ARRAY); if (!kids) return HPDF_SetError (parent->error, HPDF_PAGES_MISSING_KIDS_ENTRY, 0); if (kid->header.obj_class == (HPDF_OCLASS_DICT | HPDF_OSUBCLASS_PAGE)) { HPDF_PageAttr attr = (HPDF_PageAttr)kid->attr; attr->parent = parent; } return HPDF_Array_Add (kids, kid); }
static HPDF_STATUS AddAnnotation (HPDF_Page page, HPDF_Annotation annot) { HPDF_Array array; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE((" HPDF_Pages\n")); /* find "Annots" entry */ array = HPDF_Dict_GetItem (page, "Annots", HPDF_OCLASS_ARRAY); if (!array) { array = HPDF_Array_New (page->mmgr); if (!array) return HPDF_Error_GetCode (page->error); ret = HPDF_Dict_Add (page, "Annots", array); if (ret != HPDF_OK) return ret; } if ((ret = HPDF_Array_Add (array, annot)) != HPDF_OK) return ret; /* Add Parent to the annotation */ ret = HPDF_Dict_Add( annot, "P", page); return ret; }
HPDF_Destination_SetXYZ (HPDF_Destination dst, HPDF_REAL left, HPDF_REAL top, HPDF_REAL zoom) { HPDF_STATUS ret = HPDF_OK; HPDF_Page target; HPDF_PTRACE((" HPDF_Destination_SetXYZ\n")); if (!HPDF_Destination_Validate (dst)) return HPDF_INVALID_DESTINATION; if (left < 0 || top < 0 || zoom < 0.08 || zoom > 32) return HPDF_RaiseError (dst->error, HPDF_INVALID_PARAMETER, 0); target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT); if (dst->list->count > 1) { HPDF_Array_Clear (dst); ret += HPDF_Array_Add (dst, target); } ret += HPDF_Array_AddName (dst, HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_XYZ]); ret += HPDF_Array_AddReal (dst, left); ret += HPDF_Array_AddReal (dst, top); ret += HPDF_Array_AddReal (dst, zoom); if (ret != HPDF_OK) return HPDF_CheckError (dst->error); return HPDF_OK; }
HPDF_Destination HPDF_Destination_New (HPDF_MMgr mmgr, HPDF_Page target, HPDF_Xref xref) { HPDF_Destination dst; HPDF_PTRACE((" HPDF_Destination_New\n")); if (!HPDF_Page_Validate (target)) { HPDF_SetError (mmgr->error, HPDF_INVALID_PAGE, 0); return NULL; } dst = HPDF_Array_New (mmgr); if (!dst) return NULL; dst->header.obj_class |= HPDF_OSUBCLASS_DESTINATION; if (HPDF_Xref_Add (xref, dst) != HPDF_OK) return NULL; /* first item of array must be target page */ if (HPDF_Array_Add (dst, target) != HPDF_OK) return NULL; /* default type is HPDF_FIT */ if (HPDF_Array_AddName (dst, HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT]) != HPDF_OK) return NULL; return dst; }
HPDF_Destination_SetFitBV (HPDF_Destination dst, HPDF_REAL left) { HPDF_STATUS ret = HPDF_OK; HPDF_Page target; HPDF_PTRACE((" HPDF_Destination_SetFitBV\n")); if (!HPDF_Destination_Validate (dst)) return HPDF_INVALID_DESTINATION; target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT); if (dst->list->count > 1) { HPDF_Array_Clear (dst); ret += HPDF_Array_Add (dst, target); } ret += HPDF_Array_AddName (dst, HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_BV]); ret += HPDF_Array_AddReal (dst, left); if (ret != HPDF_OK) return HPDF_CheckError (dst->error); return HPDF_OK; }
HPDF_EXPORT(HPDF_STATUS) HPDF_U3D_Add3DView(HPDF_U3D u3d, HPDF_Dict view) { HPDF_Array views = NULL; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE ((" HPDF_Add3DView\n")); if (u3d == NULL || view == NULL) { return HPDF_INVALID_U3D_DATA; } views = (HPDF_Array)HPDF_Dict_GetItem (u3d, "VA", HPDF_OCLASS_ARRAY); if (views == NULL) { views = HPDF_Array_New (u3d->mmgr); if (!views) { return HPDF_Error_GetCode (u3d->error); } ret = HPDF_Dict_Add (u3d, "VA", views); if (ret == HPDF_OK) { ret = HPDF_Dict_AddNumber (u3d, "DV", 0); } else { HPDF_Array_Free (views); return ret; } } if (ret == HPDF_OK) { ret = HPDF_Array_Add( views, view); } return ret; }
HPDF_3DView_Add3DC3DMeasure(HPDF_Dict view, HPDF_3DMeasure measure) { HPDF_STATUS ret = HPDF_OK; HPDF_Array array; void* a; a = HPDF_Dict_GetItem (view, "MA", HPDF_OCLASS_ARRAY); if ( a ) { array = (HPDF_Array)a; } else { array = HPDF_Array_New (view->mmgr); if (!array) return 0; if (HPDF_Dict_Add (view, "MA", array) != HPDF_OK) return 0; } ret = HPDF_Array_Add(array, measure); return ret; }
HPDF_STATUS HPDF_Array_AddNull (HPDF_Array array) { HPDF_Null n = HPDF_Null_New (array->mmgr); HPDF_PTRACE (" HPDF_Array_AddNull\n"); if (!n) return HPDF_Error_GetCode (array->error); else return HPDF_Array_Add (array, n); }
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_STATUS HPDF_Array_AddReal (HPDF_Array array, HPDF_REAL value) { HPDF_Real r = HPDF_Real_New (array->mmgr, value); HPDF_PTRACE((" HPDF_Array_AddReal\n")); if (!r) return HPDF_Error_GetCode (array->error); else return HPDF_Array_Add (array, r); }
HPDF_STATUS HPDF_Array_AddName (HPDF_Array array, const char *value) { HPDF_Name n = HPDF_Name_New (array->mmgr, value); HPDF_PTRACE((" HPDF_Array_AddName\n")); if (!n) return HPDF_Error_GetCode (array->error); else return HPDF_Array_Add (array, n); }
HPDF_STATUS HPDF_Array_AddNumber (HPDF_Array array, HPDF_INT32 value) { HPDF_Number n = HPDF_Number_New (array->mmgr, value); HPDF_PTRACE((" HPDF_Array_AddNumber\n")); if (!n) return HPDF_Error_GetCode (array->error); else return HPDF_Array_Add (array, n); }
HPDF_STATUS HPDF_Doc_PrepareEncryption (HPDF_Doc pdf) { HPDF_Encrypt e= HPDF_EncryptDict_GetAttr (pdf->encrypt_dict); HPDF_Dict info = GetInfo (pdf); HPDF_Array id; if (!e) return HPDF_DOC_ENCRYPTDICT_NOT_FOUND; if (!info) return pdf->error.error_no; if (HPDF_EncryptDict_Prepare (pdf->encrypt_dict, info, pdf->xref) != HPDF_OK) return pdf->error.error_no; /* reset 'ID' to trailer-dictionary */ id = HPDF_Dict_GetItem (pdf->trailer, "ID", HPDF_OCLASS_ARRAY); if (!id) { id = HPDF_Array_New (pdf->mmgr); if (!id || HPDF_Dict_Add (pdf->trailer, "ID", id) != HPDF_OK) return pdf->error.error_no; } else HPDF_Array_Clear (id); if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr, e->encrypt_id, HPDF_ID_LEN)) != HPDF_OK) return pdf->error.error_no; if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr, e->encrypt_id, HPDF_ID_LEN)) != HPDF_OK) return pdf->error.error_no; return HPDF_OK; }
HPDF_LinkAnnot_SetBorderStyle (HPDF_Annotation annot, HPDF_REAL width, HPDF_UINT16 dash_on, HPDF_UINT16 dash_off) { HPDF_Array array; HPDF_STATUS ret; HPDF_PTRACE((" HPDF_LinkAnnot_SetBorderStyle\n")); if (!CheckSubType (annot, HPDF_ANNOT_LINK)) return HPDF_INVALID_ANNOTATION; if (width < 0) return HPDF_RaiseError (annot->error, HPDF_INVALID_PARAMETER, 0); array = HPDF_Array_New (annot->mmgr); if (!array) return HPDF_CheckError (annot->error); if ((ret = HPDF_Dict_Add (annot, "Border", array)) != HPDF_OK) return HPDF_CheckError (annot->error); ret += HPDF_Array_AddNumber (array, 0); ret += HPDF_Array_AddNumber (array, 0); ret += HPDF_Array_AddReal (array, width); if (ret != HPDF_OK) return HPDF_CheckError (annot->error); if (dash_on && dash_off) { HPDF_Array dash = HPDF_Array_New (annot->mmgr); if (!dash) return HPDF_CheckError (annot->error); if ((ret = HPDF_Array_Add (array, dash)) != HPDF_OK) return HPDF_CheckError (annot->error); ret += HPDF_Array_AddNumber (dash, dash_on); ret += HPDF_Array_AddNumber (dash, dash_off); if (ret != HPDF_OK) return HPDF_CheckError (annot->error); } return HPDF_OK; }
HPDF_STATUS HPDF_PDFA_AppendOutputIntents(HPDF_Doc pdf, const char *iccname, HPDF_Dict iccdict) { HPDF_Array intents; HPDF_Dict intent; HPDF_STATUS ret; if (!HPDF_HasDoc (pdf)) return HPDF_INVALID_DOCUMENT; /* prepare intent */ intent = HPDF_Dict_New (pdf->mmgr); ret = HPDF_Xref_Add (pdf->xref, intent); if ( ret != HPDF_OK) { HPDF_Dict_Free(intent); return ret; } ret += HPDF_Dict_AddName (intent, "Type", "OutputIntent"); ret += HPDF_Dict_AddName (intent, "S", "GTS_PDFA1"); ret += HPDF_Dict_Add (intent, "OutputConditionIdentifier", HPDF_String_New (pdf->mmgr, iccname, NULL)); ret += HPDF_Dict_Add (intent, "OutputCondition", HPDF_String_New (pdf->mmgr, iccname,NULL)); ret += HPDF_Dict_Add (intent, "Info", HPDF_String_New (pdf->mmgr, iccname, NULL)); ret += HPDF_Dict_Add (intent, "DestOutputProfile ", iccdict); if ( ret != HPDF_OK) { HPDF_Dict_Free(intent); return ret; } /* Copied from HPDF_AddIntent - not public function */ intents = HPDF_Dict_GetItem (pdf->catalog, "OutputIntents", HPDF_OCLASS_ARRAY); if (intents == NULL) { intents = HPDF_Array_New (pdf->mmgr); if (intents) { HPDF_STATUS ret = HPDF_Dict_Add (pdf->catalog, "OutputIntents", intents); if (ret != HPDF_OK) { HPDF_CheckError (&pdf->error); return HPDF_Error_GetDetailCode (&pdf->error); } } } HPDF_Array_Add(intents,intent); return HPDF_Error_GetDetailCode (&pdf->error); }
HPDF_STATUS HPDF_Catalog_AddPageLabel (HPDF_Catalog catalog, HPDF_UINT page_num, HPDF_Dict page_label) { HPDF_STATUS ret; HPDF_Array nums; HPDF_Dict labels = HPDF_Dict_GetItem (catalog, "PageLabels", HPDF_OCLASS_DICT); HPDF_PTRACE ((" HPDF_Catalog_AddPageLabel\n")); if (!labels) { labels = HPDF_Dict_New (catalog->mmgr); if (!labels) return catalog->error->error_no; if ((ret = HPDF_Dict_Add (catalog, "PageLabels", labels)) != HPDF_OK) return ret; } nums = HPDF_Dict_GetItem (labels, "Nums", HPDF_OCLASS_ARRAY); if (!nums) { nums = HPDF_Array_New (catalog->mmgr); if (!nums) return catalog->error->error_no; if ((ret = HPDF_Dict_Add (labels, "Nums", nums)) != HPDF_OK) return ret; } if ((ret = HPDF_Array_AddNumber (nums, page_num)) != HPDF_OK) return ret; return HPDF_Array_Add (nums, page_label); }
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_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; }
static HPDF_Font CIDFontType0_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_CIDFontDefAttr fontdef_attr = (HPDF_CIDFontDefAttr)fontdef->attr; HPDF_Encoder encoder = attr->encoder; HPDF_CMapEncoderAttr encoder_attr = (HPDF_CMapEncoderAttr)encoder->attr; HPDF_UINT16 save_cid = 0; HPDF_Font font; HPDF_Array array; HPDF_Array sub_array = NULL; HPDF_UINT i; HPDF_Dict descriptor; HPDF_Dict cid_system_info; HPDF_PTRACE ((" HPDF_CIDFontType0_New\n")); font = HPDF_Dict_New (parent->mmgr); if (!font) return NULL; if (HPDF_Xref_Add (xref, font) != HPDF_OK) return NULL; ret += HPDF_Dict_AddName (font, "Type", "Font"); ret += HPDF_Dict_AddName (font, "Subtype", "CIDFontType0"); ret += HPDF_Dict_AddNumber (font, "DW", fontdef_attr->DW); ret += HPDF_Dict_AddName (font, "BaseFont", fontdef->base_font); if (ret != HPDF_OK) return NULL; /* add 'DW2' element */ array = HPDF_Array_New (parent->mmgr); if (!array) return NULL; if (HPDF_Dict_Add (font, "DW2", array) != HPDF_OK) return NULL; ret += HPDF_Array_AddNumber (array, fontdef_attr->DW2[0]); ret += HPDF_Array_AddNumber (array, fontdef_attr->DW2[1]); if (ret != HPDF_OK) return NULL; /* add 'W' element */ array = HPDF_Array_New (parent->mmgr); if (!array) return NULL; if (HPDF_Dict_Add (font, "W", array) != HPDF_OK) return NULL; /* Create W array. */ for (i = 0; i< fontdef_attr->widths->count; i++) { HPDF_CID_Width *w = (HPDF_CID_Width *)HPDF_List_ItemAt (fontdef_attr->widths, i); if (w->cid != save_cid + 1 || !sub_array) { sub_array = HPDF_Array_New (parent->mmgr); if (!sub_array) return NULL; ret += HPDF_Array_AddNumber (array, w->cid); ret += HPDF_Array_Add (array, sub_array); } ret += HPDF_Array_AddNumber (sub_array, w->width); save_cid = w->cid; if (ret != HPDF_OK) return NULL; } /* create descriptor */ descriptor = HPDF_Dict_New (parent->mmgr); if (!descriptor) return NULL; if (HPDF_Xref_Add (xref, descriptor) != HPDF_OK) return NULL; if (HPDF_Dict_Add (font, "FontDescriptor", descriptor) != HPDF_OK) return NULL; ret += HPDF_Dict_AddName (descriptor, "Type", "FontDescriptor"); ret += HPDF_Dict_AddName (descriptor, "FontName", fontdef->base_font); ret += HPDF_Dict_AddNumber (descriptor, "Ascent", fontdef->ascent); ret += HPDF_Dict_AddNumber (descriptor, "Descent", fontdef->descent); ret += HPDF_Dict_AddNumber (descriptor, "CapHeight", fontdef->cap_height); ret += HPDF_Dict_AddNumber (descriptor, "MissingWidth", fontdef->missing_width); ret += HPDF_Dict_AddNumber (descriptor, "Flags", fontdef->flags); if (ret != HPDF_OK) return NULL; array = HPDF_Box_Array_New (parent->mmgr, fontdef->font_bbox); if (!array) return NULL; ret += HPDF_Dict_Add (descriptor, "FontBBox", array); ret += HPDF_Dict_AddNumber (descriptor, "ItalicAngle", fontdef->italic_angle); ret += HPDF_Dict_AddNumber (descriptor, "StemV", fontdef->stemv); if (ret != HPDF_OK) return NULL; /* create CIDSystemInfo dictionary */ cid_system_info = HPDF_Dict_New (parent->mmgr); if (!cid_system_info) return NULL; if (HPDF_Dict_Add (font, "CIDSystemInfo", cid_system_info) != HPDF_OK) return NULL; ret += HPDF_Dict_Add (cid_system_info, "Registry", HPDF_String_New (parent->mmgr, encoder_attr->registry, NULL)); ret += HPDF_Dict_Add (cid_system_info, "Ordering", HPDF_String_New (parent->mmgr, encoder_attr->ordering, NULL)); ret += HPDF_Dict_AddNumber (cid_system_info, "Supplement", encoder_attr->suppliment); if (ret != 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; }
HPDF_EXPORT(HPDF_STATUS) HPDF_3DView_AddNode(HPDF_Dict view, const char *name, HPDF_REAL opacity, HPDF_BOOL visible) { HPDF_Array nodes = NULL; HPDF_Dict node; HPDF_STATUS ret = HPDF_OK; HPDF_PTRACE ((" HPDF_3DView_AddNode\n")); if (view == NULL || opacity < 0 || opacity > 1 || name == NULL || name[0] == '\0') { return HPDF_INVALID_U3D_DATA; } nodes = (HPDF_Array)HPDF_Dict_GetItem (view, "NA", HPDF_OCLASS_ARRAY); if (nodes == NULL) { nodes = HPDF_Array_New (view->mmgr); if (!nodes) { return HPDF_Error_GetCode (view->error); } ret = HPDF_Dict_Add (view, "NA", nodes); if (ret != HPDF_OK) { HPDF_Array_Free (nodes); return ret; } } node = HPDF_Dict_New (view->mmgr); if (!node) { HPDF_Array_Free (nodes); return HPDF_Error_GetCode (view->error); } ret = HPDF_Dict_AddName (node, "Type", "3DNode"); if (ret != HPDF_OK) { HPDF_Array_Free (nodes); HPDF_Dict_Free (node); return ret; } ret = HPDF_Dict_Add (node, "N", HPDF_String_New (view->mmgr, name, NULL)); if (ret != HPDF_OK) { HPDF_Array_Free (nodes); HPDF_Dict_Free (node); return ret; } ret = HPDF_Dict_AddReal (node, "O", opacity); if (ret != HPDF_OK) { HPDF_Array_Free (nodes); HPDF_Dict_Free (node); return ret; } ret = HPDF_Dict_AddBoolean (node, "V", visible); if (ret != HPDF_OK) { HPDF_Dict_Free (node); HPDF_Array_Free (nodes); return ret; } ret = HPDF_Array_Add(nodes, node); if (ret != HPDF_OK) { HPDF_Dict_Free (node); HPDF_Array_Free (nodes); return ret; } return ret; }
static HPDF_STATUS LoadJpegHeader (HPDF_Image image, HPDF_Stream stream) { HPDF_UINT16 tag; HPDF_UINT16 height; HPDF_UINT16 width; HPDF_BYTE precision; HPDF_BYTE num_components; const char *color_space_name; HPDF_UINT len; HPDF_STATUS ret; HPDF_Array array; HPDF_PTRACE ((" HPDF_Image_LoadJpegHeader\n")); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&tag); if (tag != 0xFFD8) return HPDF_INVALID_JPEG_DATA; /* find SOF record */ for (;;) { HPDF_UINT16 size; len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&tag); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&size, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&size); HPDF_PTRACE (("tag=%04X size=%u\n", tag, size)); if (tag == 0xFFC0 || tag == 0xFFC1 || tag == 0xFFC2 || tag == 0xFFC9) { len = 1; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&precision, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&height, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&height); len = 2; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&width, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); HPDF_UInt16Swap (&width); len = 1; if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&num_components, &len) != HPDF_OK) return HPDF_Error_GetCode (stream->error); break; } else if ((tag | 0x00FF) != 0xFFFF) /* lost marker */ return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT, 0); if (HPDF_Stream_Seek (stream, size - 2, HPDF_SEEK_CUR) != HPDF_OK) return HPDF_Error_GetCode (stream->error); } if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK) return HPDF_Error_GetCode (stream->error); if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK) return HPDF_Error_GetCode (stream->error); /* classification of RGB and CMYK is less than perfect * YCbCr and YCCK are classified into RGB or CMYK. * * It is necessary to read APP14 data to distinguish colorspace perfectly. */ switch (num_components) { case 1: color_space_name = COL_GRAY; break; case 3: color_space_name = COL_RGB; break; case 4: array = HPDF_Array_New (image->mmgr); if (!array) return HPDF_Error_GetCode (stream->error); ret = HPDF_Dict_Add (image, "Decode", array); if (ret != HPDF_OK) return HPDF_Error_GetCode (stream->error); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1)); ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0)); if (ret != HPDF_OK) return HPDF_Error_GetCode (stream->error); color_space_name = COL_CMYK; break; default: return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT, 0); } if (HPDF_Dict_Add (image, "ColorSpace", HPDF_Name_New (image->mmgr, color_space_name)) != HPDF_OK) return HPDF_Error_GetCode (stream->error); if (HPDF_Dict_Add (image, "BitsPerComponent", HPDF_Number_New (image->mmgr, precision)) != HPDF_OK) return HPDF_Error_GetCode (stream->error); 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 {