X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=5186af38a9964f6f3894fc8cfb0515ff33e8a659;hb=730ba2bc226764b0273d43960924a17650d277b7;hp=9486441d77b512b506fe872c7f7b91c13fee49e0;hpb=cf5e3fe142c55ec2ca1850087c173c7f6ee4eb9b;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index 9486441..5186af3 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -23,6 +23,12 @@ #include #include #include "../config.h" +#ifdef HAVE_DIRENT_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif #ifdef HAVE_FONTCONFIG_H #include #endif @@ -104,8 +110,8 @@ struct mapping { {"ZapfDingbats", "d050000l"}}; class SWFOutputDev: public OutputDev { - struct swfoutput output; int outputstarted; + struct swfoutput output; public: // Constructor. @@ -113,8 +119,13 @@ public: // 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 @@ -230,6 +241,9 @@ public: 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); @@ -238,15 +252,19 @@ class InfoOutputDev: public OutputDev { 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;} @@ -265,23 +283,28 @@ class InfoOutputDev: public OutputDev } 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++; } }; @@ -300,8 +323,39 @@ SWFOutputDev::SWFOutputDev() 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(x2user_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) { @@ -646,7 +700,7 @@ void SWFOutputDev::stroke(GfxState *state) 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(" stroke\n"); dump_outline(outline); } @@ -682,7 +736,7 @@ void SWFOutputDev::fill(GfxState *state) 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(" fill\n"); dump_outline(outline); } @@ -699,7 +753,7 @@ void SWFOutputDev::eoFill(GfxState *state) 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(" eofill\n"); dump_outline(outline); } @@ -717,7 +771,7 @@ void SWFOutputDev::clip(GfxState *state) m.m13 = 0; m.m23 = 0; SWF_OUTLINE*outline = gfxPath_to_SWF_OUTLINE(state, path); - if(screenloglevel >= LOGLEVEL_TRACE) { + if(getLogLevel() >= LOGLEVEL_TRACE) { msg(" clip\n"); dump_outline(outline); } @@ -734,7 +788,7 @@ void SWFOutputDev::eoClip(GfxState *state) 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(" eoclip\n"); dump_outline(outline); } @@ -743,9 +797,9 @@ void SWFOutputDev::eoClip(GfxState *state) 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() @@ -879,13 +933,21 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl if(x2 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(" 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) @@ -1847,10 +1909,15 @@ static void printInfoDate(Dict *infoDict, char *key, char *fmt) { void pdfswf_setparameter(char*name, char*value) { + msg(" 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); } @@ -1867,6 +1934,82 @@ void pdfswf_addfont(char*filename) } } +static char* dirseparator() +{ +#ifdef WIN32 + return "\\"; +#else + return "/"; +#endif +} + +void pdfswf_addlanguagedir(char*dir) +{ + if(!globalParams) + globalParams = new GlobalParams(""); + + msg(" 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(" Could not open %s"); + return; + } + globalParams->parseFile(new GString(config_file), fi); + fclose(fi); +} + +void pdfswf_addfontdir(char*dirname) +{ +#ifdef HAVE_DIRENT_H + msg(" Adding %s to font directories", dirname); + DIR*dir = opendir(dirname); + if(!dir) { + msg(" 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(" Adding %s to fonts", fontname); + pdfswf_addfont(fontname); + } + } + closedir(dir); +#else + msg(" No dirent.h- unable to add font dir %s"); +#endif +} + + typedef struct _pdf_doc_internal { int protect; @@ -1893,7 +2036,8 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword) Object info; // read config file - globalParams = new GlobalParams(""); + if(!globalParams) + globalParams = new GlobalParams(""); // open PDF file if (userPassword && userPassword[0]) { @@ -1912,7 +2056,7 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword) // 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"); @@ -1940,8 +2084,8 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword) 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; @@ -1970,7 +2114,7 @@ class MemCheck { public: ~MemCheck() { - delete globalParams; + delete globalParams;globalParams=0; Object::memCheck(stderr); gMemReport(stderr); } @@ -1992,6 +2136,9 @@ void pdf_destroy(pdf_doc_t*pdf_doc) 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)); @@ -2028,10 +2175,12 @@ void swf_output_setparameter(swf_output_t*swf_output, char*name, char*value) 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) @@ -2042,11 +2191,10 @@ 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"); @@ -2057,13 +2205,61 @@ void pdf_page_render(pdf_page_t*page, swf_output_t*output) #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); +}