const char* HPDF_StrStr (const char *s1, const char *s2, HPDF_UINT maxlen) { HPDF_UINT len = HPDF_StrLen (s2, -1); if (!s1) return NULL; if (len == 0) return s1; if (maxlen == 0) maxlen = HPDF_StrLen (s1, -1); if (maxlen < len) return NULL; maxlen -= len; maxlen++; while (maxlen > 0) { if (HPDF_MemCmp ((HPDF_BYTE *)s1, (HPDF_BYTE *)s2, len) == 0) return s1; s1++; maxlen--; } return NULL; }
HPDF_Page_MeasureText (HPDF_Page page, const char *text, HPDF_REAL width, HPDF_BOOL wordwrap, HPDF_REAL *real_width) { HPDF_PageAttr attr; HPDF_UINT len = HPDF_StrLen(text, HPDF_LIMIT_MAX_STRING_LEN + 1); HPDF_UINT ret; if (!HPDF_Page_Validate (page) || len == 0) return 0; attr = (HPDF_PageAttr )page->attr; HPDF_PTRACE((" HPDF_Page_MeasureText\n")); /* no font exists */ if (!attr->gstate->font) { HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0); return 0; } ret = HPDF_Font_MeasureText (attr->gstate->font, (HPDF_BYTE *)text, len, width, attr->gstate->font_size, attr->gstate->char_space, attr->gstate->word_space, wordwrap, real_width); HPDF_CheckError (page->error); return ret; }
HPDF_Page_CreateURILinkAnnot (HPDF_Page page, HPDF_Rect rect, const char *uri) { HPDF_PageAttr attr; HPDF_Annotation annot; HPDF_PTRACE((" HPDF_Page_CreateURILinkAnnot\n")); if (!HPDF_Page_Validate (page)) return NULL; attr = (HPDF_PageAttr)page->attr; if (HPDF_StrLen (uri, HPDF_LIMIT_MAX_STRING_LEN) <= 0) { HPDF_RaiseError (page->error, HPDF_INVALID_URI, 0); return NULL; } annot = HPDF_URILinkAnnot_New (page->mmgr, attr->xref, rect, uri); if (annot) { if (AddAnnotation (page, annot) != HPDF_OK) { HPDF_CheckError (page->error); annot = NULL; } } else HPDF_CheckError (page->error); return annot; }
HPDF_Page_TextWidth (HPDF_Page page, const char *text) { HPDF_PageAttr attr; HPDF_TextWidth tw; HPDF_REAL ret = 0; HPDF_UINT len = HPDF_StrLen(text, HPDF_LIMIT_MAX_STRING_LEN + 1); HPDF_PTRACE((" HPDF_Page_TextWidth\n")); if (!HPDF_Page_Validate (page) || len == 0) return 0; attr = (HPDF_PageAttr )page->attr; /* no font exists */ if (!attr->gstate->font) { HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0); return 0; } tw = HPDF_Font_TextWidth (attr->gstate->font, (HPDF_BYTE *)text, len); ret += attr->gstate->word_space * tw.numspace; ret += tw.width * attr->gstate->font_size / 1000; ret += attr->gstate->char_space * tw.numchars; HPDF_CheckError (page->error); return ret; }
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; }
/* 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; }
static const char* GetKeyword (const char *src, char *keyword, HPDF_UINT len) { HPDF_UINT src_len = HPDF_StrLen (src, -1); HPDF_PTRACE (" GetKeyword\n"); if (!keyword || src_len == 0 || len == 0) return NULL; *keyword = 0; while (len > 1) { if (HPDF_IS_WHITE_SPACE(*src)) { *keyword = 0; while (HPDF_IS_WHITE_SPACE(*src)) src++; return src; } *keyword++ = *src++; len--; } *keyword = 0; return NULL; }
HPDF_STATUS HPDF_EncryptDict_SetPassword (HPDF_EncryptDict dict, const char *owner_passwd, const char *user_passwd) { HPDF_Encrypt attr = (HPDF_Encrypt)dict->attr; HPDF_PTRACE((" HPDF_EncryptDict_SetPassword\n")); if (HPDF_StrLen(owner_passwd, 2) == 0) return HPDF_SetError(dict->error, HPDF_ENCRYPT_INVALID_PASSWORD, 0); if (owner_passwd && user_passwd && HPDF_StrCmp (owner_passwd, user_passwd) == 0) return HPDF_SetError(dict->error, HPDF_ENCRYPT_INVALID_PASSWORD, 0); HPDF_PadOrTrancatePasswd (owner_passwd, attr->owner_passwd); HPDF_PadOrTrancatePasswd (user_passwd, attr->user_passwd); return HPDF_OK; }
HPDF_STATUS HPDF_String_Write (HPDF_String obj, HPDF_Stream stream, HPDF_Encrypt e) { HPDF_STATUS ret; /* * When encoder is not NULL, text is changed to unicode using encoder, * and it outputs by HPDF_write_binary method. */ HPDF_PTRACE((" HPDF_String_Write\n")); if (e) HPDF_Encrypt_Reset (e); if (obj->encoder == NULL) { if (e) { if ((ret = HPDF_Stream_WriteChar (stream, '<')) != HPDF_OK) return ret; if ((ret = HPDF_Stream_WriteBinary (stream, obj->value, HPDF_StrLen ((char *)obj->value, -1), e)) != HPDF_OK) return ret; return HPDF_Stream_WriteChar (stream, '>'); } else { return HPDF_Stream_WriteEscapeText (stream, (char *)obj->value); } } else { HPDF_BYTE* src = obj->value; HPDF_BYTE buf[HPDF_TEXT_DEFAULT_LEN * 2]; HPDF_UINT tmp_len = 0; HPDF_BYTE* pbuf = buf; HPDF_INT32 len = obj->len; HPDF_ParseText_Rec parse_state; HPDF_UINT i; if ((ret = HPDF_Stream_WriteChar (stream, '<')) != HPDF_OK) return ret; if ((ret = HPDF_Stream_WriteBinary (stream, UNICODE_HEADER, 2, e)) != HPDF_OK) return ret; HPDF_Encoder_SetParseText (obj->encoder, &parse_state, src, len); for (i = 0; i < len; i++) { HPDF_BYTE b = src[i]; HPDF_UNICODE tmp_unicode; HPDF_ByteType btype = HPDF_Encoder_ByteType (obj->encoder, &parse_state); if (tmp_len >= HPDF_TEXT_DEFAULT_LEN - 1) { if ((ret = HPDF_Stream_WriteBinary (stream, buf, tmp_len * 2, e)) != HPDF_OK) return ret; tmp_len = 0; pbuf = buf; } if (btype != HPDF_BYTE_TYPE_TRIAL) { if (btype == HPDF_BYTE_TYPE_LEAD) { HPDF_BYTE b2 = src[i + 1]; HPDF_UINT16 char_code = (HPDF_UINT) b * 256 + b2; tmp_unicode = HPDF_Encoder_ToUnicode (obj->encoder, char_code); } else { tmp_unicode = HPDF_Encoder_ToUnicode (obj->encoder, b); } HPDF_UInt16Swap (&tmp_unicode); HPDF_MemCpy (pbuf, (HPDF_BYTE*)&tmp_unicode, 2); pbuf += 2; tmp_len++; } } if (tmp_len > 0) { if ((ret = HPDF_Stream_WriteBinary (stream, buf, tmp_len * 2, e)) != HPDF_OK) return ret; } if ((ret = HPDF_Stream_WriteChar (stream, '>')) != HPDF_OK) return ret; } return HPDF_OK; }
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; }
void HPDF_EncryptDict_CreateID (HPDF_EncryptDict dict, HPDF_Dict info, HPDF_Xref xref) { HPDF_MD5_CTX ctx; HPDF_Encrypt attr = (HPDF_Encrypt)dict->attr; /* use the result of 'time' function to get random value. * when debugging, 'time' value is ignored. */ #ifndef HPDF_DEBUG time_t t = HPDF_TIME (NULL); #endif /* HPDF_DEBUG */ HPDF_MD5Init (&ctx); #ifndef HPDF_DEBUG HPDF_MD5Update(&ctx, (HPDF_BYTE *)&t, sizeof(t)); /* create File Identifier from elements of Into dictionary. */ if (info) { const char *s; HPDF_UINT len; /* Author */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_AUTHOR); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); /* Creator */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_CREATOR); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); /* Producer */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_PRODUCER); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); /* Title */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_TITLE); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); /* Subject */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_SUBJECT); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); /* Keywords */ s = HPDF_Info_GetInfoAttr (info, HPDF_INFO_KEYWORDS); if ((len = HPDF_StrLen (s, -1)) > 0) HPDF_MD5Update(&ctx, (const HPDF_BYTE *)s, len); HPDF_MD5Update(&ctx, (const HPDF_BYTE *)&(xref->entries->count), sizeof(HPDF_UINT32)); } #endif HPDF_MD5Final(attr->encrypt_id, &ctx); }