mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 21:04:26 +00:00
184 lines
3.4 KiB
C
184 lines
3.4 KiB
C
![]() |
#include <fitz.h>
|
||
|
#include <mupdf.h>
|
||
|
|
||
|
typedef struct pdf_item_s pdf_item;
|
||
|
|
||
|
struct pdf_item_s
|
||
|
{
|
||
|
pdf_itemkind kind;
|
||
|
fz_obj *key;
|
||
|
void *val;
|
||
|
pdf_item *next;
|
||
|
};
|
||
|
|
||
|
struct refkey
|
||
|
{
|
||
|
pdf_itemkind kind;
|
||
|
int oid;
|
||
|
int gen;
|
||
|
};
|
||
|
|
||
|
struct pdf_store_s
|
||
|
{
|
||
|
fz_hashtable *hash; /* hash for oid/gen keys */
|
||
|
pdf_item *root; /* linked list for everything else */
|
||
|
};
|
||
|
|
||
|
fz_error *
|
||
|
pdf_newstore(pdf_store **storep)
|
||
|
{
|
||
|
fz_error *error;
|
||
|
pdf_store *store;
|
||
|
|
||
|
store = fz_malloc(sizeof(pdf_store));
|
||
|
if (!store)
|
||
|
return fz_outofmem;
|
||
|
|
||
|
error = fz_newhash(&store->hash, 4096, sizeof(struct refkey));
|
||
|
if (error)
|
||
|
{
|
||
|
fz_free(store);
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
store->root = nil;
|
||
|
|
||
|
*storep = store;
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
static void dropitem(pdf_itemkind kind, void *val)
|
||
|
{
|
||
|
switch (kind)
|
||
|
{
|
||
|
case PDF_KCOLORSPACE: fz_dropcolorspace(val); break;
|
||
|
case PDF_KFUNCTION: pdf_dropfunction(val); break;
|
||
|
case PDF_KXOBJECT: pdf_dropxobject(val); break;
|
||
|
case PDF_KIMAGE: fz_dropimage(val); break;
|
||
|
case PDF_KPATTERN: pdf_droppattern(val); break;
|
||
|
case PDF_KSHADE: fz_dropshade(val); break;
|
||
|
case PDF_KCMAP: pdf_dropcmap(val); break;
|
||
|
case PDF_KFONT: fz_dropfont(val); break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
pdf_emptystore(pdf_store *store)
|
||
|
{
|
||
|
pdf_item *item;
|
||
|
pdf_item *next;
|
||
|
struct refkey *key;
|
||
|
void *val;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < fz_hashlen(store->hash); i++)
|
||
|
{
|
||
|
key = fz_hashgetkey(store->hash, i);
|
||
|
val = fz_hashgetval(store->hash, i);
|
||
|
if (val)
|
||
|
dropitem(key->kind, val);
|
||
|
}
|
||
|
fz_emptyhash(store->hash);
|
||
|
|
||
|
for (item = store->root; item; item = next)
|
||
|
{
|
||
|
next = item->next;
|
||
|
fz_dropobj(item->key);
|
||
|
dropitem(item->kind, item->val);
|
||
|
fz_free(item);
|
||
|
}
|
||
|
|
||
|
store->root = nil;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
pdf_dropstore(pdf_store *store)
|
||
|
{
|
||
|
pdf_emptystore(store);
|
||
|
fz_drophash(store->hash);
|
||
|
fz_free(store);
|
||
|
}
|
||
|
|
||
|
fz_error *
|
||
|
pdf_storeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key, void *val)
|
||
|
{
|
||
|
fz_error *error;
|
||
|
|
||
|
switch (kind)
|
||
|
{
|
||
|
case PDF_KCOLORSPACE: fz_keepcolorspace(val); break;
|
||
|
case PDF_KFUNCTION: pdf_keepfunction(val); break;
|
||
|
case PDF_KXOBJECT: pdf_keepxobject(val); break;
|
||
|
case PDF_KIMAGE: fz_keepimage(val); break;
|
||
|
case PDF_KPATTERN:
|
||
|
pdf_keeppattern(val);
|
||
|
break;
|
||
|
case PDF_KSHADE: fz_keepshade(val); break;
|
||
|
case PDF_KCMAP: pdf_keepcmap(val); break;
|
||
|
case PDF_KFONT: fz_keepfont(val); break;
|
||
|
}
|
||
|
|
||
|
if (fz_isindirect(key))
|
||
|
{
|
||
|
struct refkey item;
|
||
|
|
||
|
pdf_logrsrc("store item %d: %d %d R = %p\n", kind, fz_tonum(key), fz_togen(key), val);
|
||
|
|
||
|
item.kind = kind;
|
||
|
item.oid = fz_tonum(key);
|
||
|
item.gen = fz_togen(key);
|
||
|
|
||
|
error = fz_hashinsert(store->hash, &item, val);
|
||
|
if (error)
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
pdf_item *item;
|
||
|
|
||
|
item = fz_malloc(sizeof(pdf_item));
|
||
|
if (!item)
|
||
|
return fz_outofmem;
|
||
|
|
||
|
pdf_logrsrc("store item %d: ... = %p\n", kind, val);
|
||
|
|
||
|
item->kind = kind;
|
||
|
item->key = fz_keepobj(key);
|
||
|
item->val = val;
|
||
|
|
||
|
item->next = store->root;
|
||
|
store->root = item;
|
||
|
}
|
||
|
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
void *
|
||
|
pdf_finditem(pdf_store *store, pdf_itemkind kind, fz_obj *key)
|
||
|
{
|
||
|
pdf_item *item;
|
||
|
struct refkey refkey;
|
||
|
|
||
|
if (key == nil)
|
||
|
return nil;
|
||
|
|
||
|
if (fz_isindirect(key))
|
||
|
{
|
||
|
refkey.kind = kind;
|
||
|
refkey.oid = fz_tonum(key);
|
||
|
refkey.gen = fz_togen(key);
|
||
|
return fz_hashfind(store->hash, &refkey);
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
for (item = store->root; item; item = item->next)
|
||
|
if (item->kind == kind && !fz_objcmp(item->key, key))
|
||
|
return item->val;
|
||
|
}
|
||
|
|
||
|
return nil;
|
||
|
}
|
||
|
|