Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/* 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(&ltime);

    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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;

}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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);
}
Esempio n. 20
0
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);
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
        }
Esempio n. 23
0
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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 {