+char* pdf_doc_getinfo(gfxdocument_t*doc, const char*name)
+{
+ pdf_doc_internal_t*i= (pdf_doc_internal_t*)doc->internal;
+ if(!strcmp(name, "title")) return getInfoString(i->docinfo.getDict(), "Title");
+ else if(!strcmp(name, "subject")) return getInfoString(i->docinfo.getDict(), "Subject");
+ else if(!strcmp(name, "keywords")) return getInfoString(i->docinfo.getDict(), "Keywords");
+ else if(!strcmp(name, "author")) return getInfoString(i->docinfo.getDict(), "Author");
+ else if(!strcmp(name, "creator")) return getInfoString(i->docinfo.getDict(), "Creator");
+ else if(!strcmp(name, "producer")) return getInfoString(i->docinfo.getDict(), "Producer");
+ else if(!strcmp(name, "creationdate")) return getInfoDate(i->docinfo.getDict(), "CreationDate");
+ else if(!strcmp(name, "moddate")) return getInfoDate(i->docinfo.getDict(), "ModDate");
+ else if(!strcmp(name, "linearized")) return strdup(i->doc->isLinearized() ? "yes" : "no");
+ else if(!strcmp(name, "tagged")) return strdup(i->doc->getStructTreeRoot()->isDict() ? "yes" : "no");
+ else if(!strcmp(name, "encrypted")) return strdup(i->doc->isEncrypted() ? "yes" : "no");
+ else if(!strcmp(name, "oktoprint")) return strdup(i->doc->okToPrint() ? "yes" : "no");
+ else if(!strcmp(name, "oktocopy")) return strdup(i->doc->okToCopy() ? "yes" : "no");
+ else if(!strcmp(name, "oktochange")) return strdup(i->doc->okToChange() ? "yes" : "no");
+ else if(!strcmp(name, "oktoaddnotes")) return strdup(i->doc->okToAddNotes() ? "yes" : "no");
+ else if(!strcmp(name, "version")) {
+ char buf[32];
+ sprintf(buf, "%.1f", i->doc->getPDFVersion());
+ return strdup(buf);
+ }
+ return 0;
+}
+
+
+static void pdf_set_parameter(gfxsource_t*src, const char*name, const char*value)