#include <string.h>
#include <unistd.h>
#include "../config.h"
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#ifdef HAVE_FONTCONFIG_H
#include <fontconfig.h>
#endif
{"ZapfDingbats", "d050000l"}};
class SWFOutputDev: public OutputDev {
- struct swfoutput output;
int outputstarted;
+ struct swfoutput output;
public:
// Constructor.
// Destructor.
virtual ~SWFOutputDev() ;
+
+ void setMove(int x,int y);
+ void setClip(int x1,int y1,int x2,int y2);
- void save(char*filename);
+ int save(char*filename);
+
+ void getDimensions(int*x1,int*y1,int*x2,int*y2);
//----- get info about output device
char* substitutetarget[256];
char* substitutesource[256];
int substitutepos;
+
+ int user_movex,user_movey;
+ int user_clipx1,user_clipx2,user_clipy1,user_clipy2;
};
static char*getFontID(GfxFont*font);
{
public:
int x1,y1,x2,y2;
- int has_links;
- int has_images;
+ int num_links;
+ int num_images;
+ int num_fonts;
InfoOutputDev()
{
- has_links = 0;
- has_images = 0;
+ num_links = 0;
+ num_images = 0;
+ num_fonts = 0;
+ }
+ virtual ~InfoOutputDev()
+ {
}
- virtual ~InfoOutputDev() {}
virtual GBool upsideDown() {return gTrue;}
virtual GBool useDrawChar() {return gTrue;}
virtual GBool useGradients() {return gTrue;}
}
virtual void drawLink(Link *link, Catalog *catalog)
{
- has_links = 1;
+ num_links++;
}
virtual void updateFont(GfxState *state)
{
- char*id = getFontID(state->getFont());
+ GfxFont*font = state->getFont();
+ if(!font)
+ return;
+ char*id = getFontID(font);
+ /* FIXME*/
+ num_fonts++;
}
virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg)
{
- has_images = 1;
+ num_images++;
}
virtual void drawImage(GfxState *state, Object *ref, Stream *str,
int width, int height, GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg)
{
- has_images = 1;
+ num_images++;
}
};
pic_id = 0;
substitutepos = 0;
type3Warning = 0;
+ user_movex = 0;
+ user_movey = 0;
+ user_clipx1 = 0;
+ user_clipy1 = 0;
+ user_clipx2 = 0;
+ user_clipy2 = 0;
+ memset(&output, 0, sizeof(output));
// printf("SWFOutputDev::SWFOutputDev() \n");
};
+
+void SWFOutputDev::setMove(int x,int y)
+{
+ this->user_movex = x;
+ this->user_movey = y;
+}
+
+void SWFOutputDev::setClip(int x1,int y1,int x2,int y2)
+{
+ if(x2<x1) {int x3=x1;x1=x2;x2=x3;}
+ if(y2<y1) {int y3=y1;y1=y2;y2=y3;}
+
+ this->user_clipx1 = x1;
+ this->user_clipy1 = y1;
+ this->user_clipx2 = x2;
+ this->user_clipy2 = y2;
+}
+void SWFOutputDev::getDimensions(int*x1,int*y1,int*x2,int*y2)
+{
+ if(x1) *x1 = output.swf.movieSize.xmin/20;
+ if(y1) *y1 = output.swf.movieSize.ymin/20;
+ if(x2) *x2 = output.swf.movieSize.xmax/20;
+ if(y2) *y2 = output.swf.movieSize.ymax/20;
+}
static char*getFontID(GfxFont*font)
{
m.m12 = 0; m.m13 = 0; m.m23 = 0;
SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path);
- if(screenloglevel >= LOGLEVEL_TRACE) {
+ if(getLogLevel() >= LOGLEVEL_TRACE) {
msg("<trace> stroke\n");
dump_outline(outline);
}
m.m12 = 0; m.m13 = 0; m.m23 = 0;
SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path);
- if(screenloglevel >= LOGLEVEL_TRACE) {
+ if(getLogLevel() >= LOGLEVEL_TRACE) {
msg("<trace> fill\n");
dump_outline(outline);
}
m.m12 = 0; m.m13 = 0; m.m23 = 0;
SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path);
- if(screenloglevel >= LOGLEVEL_TRACE) {
+ if(getLogLevel() >= LOGLEVEL_TRACE) {
msg("<trace> eofill\n");
dump_outline(outline);
}
m.m13 = 0; m.m23 = 0;
SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path);
- if(screenloglevel >= LOGLEVEL_TRACE) {
+ if(getLogLevel() >= LOGLEVEL_TRACE) {
msg("<trace> clip\n");
dump_outline(outline);
}
m.m12 = 0; m.m13 = 0; m.m23 = 0;
SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path);
- if(screenloglevel >= LOGLEVEL_TRACE) {
+ if(getLogLevel() >= LOGLEVEL_TRACE) {
msg("<trace> eoclip\n");
dump_outline(outline);
}
clipping[clippos] ++;
free_outline(outline);
}
-void SWFOutputDev::save(char*filename)
+int SWFOutputDev::save(char*filename)
{
- swfoutput_save(&output, filename);
+ return swfoutput_save(&output, filename);
}
SWFOutputDev::~SWFOutputDev()
if(x2<x1) {double x3=x1;x1=x2;x2=x3;}
if(y2<y1) {double y3=y1;y1=y2;y2=y3;}
+ /* apply user clip box */
+ if(user_clipx1|user_clipy1|user_clipx2|user_clipy2) {
+ if(user_clipx1 > x1) x1 = user_clipx1;
+ if(user_clipx2 < x2) x2 = user_clipx2;
+ if(user_clipy1 > y1) y1 = user_clipy1;
+ if(user_clipy2 < y2) y2 = user_clipy2;
+ }
+
if(!outputstarted) {
msg("<verbose> Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2);
swfoutput_init(&output);
outputstarted = 1;
}
- swfoutput_newpage(&output, pageNum, (int)x1, (int)y1, (int)x2, (int)y2);
+ swfoutput_newpage(&output, pageNum, user_movex, user_movey, (int)x1, (int)y1, (int)x2, (int)y2);
}
void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
void pdfswf_setparameter(char*name, char*value)
{
+ msg("<verbose> setting parameter %s to \"%s\"", name, value);
if(!strcmp(name, "caplinewidth")) {
caplinewidth = atof(value);
} else if(!strcmp(name, "zoom")) {
zoom = atoi(value);
+ } else if(!strcmp(name, "fontdir")) {
+ pdfswf_addfontdir(value);
+ } else if(!strcmp(name, "languagedir")) {
+ pdfswf_addlanguagedir(value);
} else {
swfoutput_setparameter(name, value);
}
}
}
+static char* dirseparator()
+{
+#ifdef WIN32
+ return "\\";
+#else
+ return "/";
+#endif
+}
+
+void pdfswf_addlanguagedir(char*dir)
+{
+ if(!globalParams)
+ globalParams = new GlobalParams("");
+
+ msg("<notice> Adding %s to language pack directories", dir);
+
+ int l;
+ FILE*fi = 0;
+ char* config_file = (char*)malloc(strlen(dir)+256);
+ strcpy(config_file, dir);
+ strcat(config_file, dirseparator());
+ strcat(config_file, "add-to-xpdfrc");
+
+ fi = fopen(config_file, "rb");
+ if(!fi) {
+ msg("<error> Could not open %s");
+ return;
+ }
+ globalParams->parseFile(new GString(config_file), fi);
+ fclose(fi);
+}
+
+void pdfswf_addfontdir(char*dirname)
+{
+#ifdef HAVE_DIRENT_H
+ msg("<notice> Adding %s to font directories", dirname);
+ DIR*dir = opendir(dirname);
+ if(!dir) {
+ msg("<warning> Couldn't open directory %s\n", dirname);
+ return;
+ }
+ struct dirent*ent;
+ while(1) {
+ ent = readdir (dir);
+ if (!ent)
+ break;
+ int l;
+ char*name = ent->d_name;
+ char type = 0;
+ if(!name) continue;
+ l=strlen(name);
+ if(l<4)
+ continue;
+ if(!strncasecmp(&name[l-4], ".pfa", 4))
+ type=1;
+ if(!strncasecmp(&name[l-4], ".pfb", 4))
+ type=3;
+ if(!strncasecmp(&name[l-4], ".ttf", 4))
+ type=2;
+ if(type)
+ {
+ char*fontname = (char*)malloc(strlen(dirname)+strlen(name)+2);
+ strcpy(fontname, dirname);
+ strcat(fontname, dirseparator());
+ strcat(fontname, name);
+ msg("<verbose> Adding %s to fonts", fontname);
+ pdfswf_addfont(fontname);
+ }
+ }
+ closedir(dir);
+#else
+ msg("<warning> No dirent.h- unable to add font dir %s");
+#endif
+}
+
+
typedef struct _pdf_doc_internal
{
int protect;
Object info;
// read config file
- globalParams = new GlobalParams("");
+ if(!globalParams)
+ globalParams = new GlobalParams("");
// open PDF file
if (userPassword && userPassword[0]) {
// print doc info
i->doc->getDocInfo(&info);
if (info.isDict() &&
- (screenloglevel>=LOGLEVEL_NOTICE)) {
+ (getScreenLogLevel()>=LOGLEVEL_NOTICE)) {
printInfoString(info.getDict(), "Title", "Title: %s\n");
printInfoString(info.getDict(), "Subject", "Subject: %s\n");
printInfoString(info.getDict(), "Keywords", "Keywords: %s\n");
i->protect = 0;
if (i->doc->isEncrypted()) {
if(!i->doc->okToCopy()) {
- printf("PDF disallows copying. Terminating.\n");
- exit(1); //bail out
+ printf("PDF disallows copying.\n");
+ return 0;
}
if(!i->doc->okToChange() || !i->doc->okToAddNotes())
i->protect = 1;
{
public: ~MemCheck()
{
- delete globalParams;
+ delete globalParams;globalParams=0;
Object::memCheck(stderr);
gMemReport(stderr);
}
pdf_page_t* pdf_getpage(pdf_doc_t*pdf_doc, int page)
{
pdf_doc_internal_t*di= (pdf_doc_internal_t*)pdf_doc->internal;
+
+ if(page < 1 || page > pdf_doc->num_pages)
+ return 0;
pdf_page_t* pdf_page = (pdf_page_t*)malloc(sizeof(pdf_page_t));
pdf_page_internal_t*pi= (pdf_page_internal_t*)malloc(sizeof(pdf_page_internal_t));
pdfswf_setparameter(name, value);
}
-void swf_output_save(swf_output_t*swf, char*filename)
+int swf_output_save(swf_output_t*swf, char*filename)
{
swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
- i->outputDev->save(filename);
+ int ret = i->outputDev->save(filename);
+ i->outputDev->getDimensions(&swf->x1, &swf->y1, &swf->x2, &swf->y2);
+ return ret;
}
void swf_output_destroy(swf_output_t*output)
free(output);
}
-
-void pdf_page_render(pdf_page_t*page, swf_output_t*output)
+void pdf_page_render2(pdf_page_t*page, swf_output_t*swf)
{
pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
- swf_output_internal_t*si = (swf_output_internal_t*)output->internal;
+ swf_output_internal_t*si = (swf_output_internal_t*)swf->internal;
if(pi->protect) {
swfoutput_setparameter("protect", "1");
#else
pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
#endif
+ si->outputDev->getDimensions(&swf->x1, &swf->y1, &swf->x2, &swf->y2);
}
+void pdf_page_rendersection(pdf_page_t*page, swf_output_t*output, int x, int y, int x1, int y1, int x2, int y2)
+{
+ pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
+ swf_output_internal_t*si = (swf_output_internal_t*)output->internal;
+
+ si->outputDev->setMove(x,y);
+ if((x1|y1|x2|y2)==0) x2++;
+ si->outputDev->setClip(x1,y1,x2,y2);
+
+ pdf_page_render2(page, output);
+}
+void pdf_page_render(pdf_page_t*page, swf_output_t*output)
+{
+ pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
+ swf_output_internal_t*si = (swf_output_internal_t*)output->internal;
+
+ si->outputDev->setMove(0,0);
+ si->outputDev->setClip(0,0,0,0);
+
+ pdf_page_render2(page, output);
+}
+
+
pdf_page_info_t* pdf_page_getinfo(pdf_page_t*page)
{
+ pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
pdf_page_internal_t*i= (pdf_page_internal_t*)page->internal;
pdf_page_info_t*info = (pdf_page_info_t*)malloc(sizeof(pdf_page_info_t));
memset(info, 0, sizeof(pdf_page_info_t));
+
+ InfoOutputDev*output = new InfoOutputDev;
+
+#ifdef XPDF_101
+ pi->doc->displayPage((OutputDev*)output, page->nr, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1);
+#else
+ pi->doc->displayPage((OutputDev*)output, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
+#endif
+
+ info->xMin = output->x1;
+ info->yMin = output->y1;
+ info->xMax = output->x2;
+ info->yMax = output->y2;
+ info->number_of_images = output->num_images;
+ info->number_of_links = output->num_links;
+ info->number_of_fonts = output->num_fonts;
+
+ delete output;
+
return info;
}
+void pdf_page_info_destroy(pdf_page_info_t*info)
+{
+ free(info);
+}