X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2FSWFOutputDev.cc;h=bf172122192cb4faa9c2d16be6617b24cc479c90;hb=0a162092f2e591374358ab802debe969936e9c86;hp=2f2b8079f66d7a4a3c0d7ef99a5a86a3d0730144;hpb=a8e41ad8448d32836af0c87f4da8774454de6145;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index 2f2b807..bf17212 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -63,7 +63,7 @@ #include "SWFOutputDev.h" //swftools header files -#include "swfoutput.h" +#include "../lib/devices/swf.h" #include "../lib/log.h" #include "../lib/gfxdevice.h" #include "../lib/gfxtools.h" @@ -93,12 +93,6 @@ static int fontnum = 0; static int config_use_fontconfig = 1; -// swf <-> pdf pages -// TODO: move into pdf_doc_t -static int*pages = 0; -static int pagebuflen = 0; -static int pagepos = 0; - /* config */ static double caplinewidth = 3.0; static double zoom = 72; /* xpdf: 86 */ @@ -107,6 +101,8 @@ static int forceType0Fonts = 1; static void printInfoString(Dict *infoDict, char *key, char *fmt); static void printInfoDate(Dict *infoDict, char *key, char *fmt); +static char* lastfontdir = 0; + struct mapping { char*pdffont; char*filename; @@ -169,7 +165,7 @@ public: virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ; void endframe(); - void* getSWF(); + void* get(char*name); //----- get info about output device @@ -302,6 +298,57 @@ public: gfxmatrix_t current_font_matrix; fontlist_t* fontlist; + + int*pages; + int pagebuflen; + int pagepos; + + friend void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage); +}; + +typedef struct _drawnchar +{ + gfxcoord_t x,y; + int charid; + gfxcolor_t color; +} drawnchar_t; + +class CharBuffer +{ + drawnchar_t * chars; + int buf_size; + int num_chars; + +public: + + CharBuffer() + { + buf_size = 32; + chars = (drawnchar_t*)malloc(sizeof(drawnchar_t)*buf_size); + memset(chars, 0, sizeof(drawnchar_t)*buf_size); + num_chars = 0; + } + ~CharBuffer() + { + free(chars);chars = 0; + } + + void grow(int size) + { + if(size>=buf_size) { + buf_size += 32; + chars = (drawnchar_t*)realloc(chars, sizeof(drawnchar_t)*buf_size); + } + } + + void addChar(int charid, gfxcoord_t x, gfxcoord_t y, gfxcolor_t color) + { + grow(num_chars); + chars[num_chars].x = x; + chars[num_chars].y = y; + chars[num_chars].color = color; + chars[num_chars].charid = charid; + } }; static char*getFontID(GfxFont*font); @@ -438,6 +485,9 @@ SWFOutputDev::SWFOutputDev() fontlist = 0; result = 0; outer_clip_box = 0; + pages = 0; + pagebuflen = 0; + pagepos = 0; output = (gfxdevice_t*)malloc(sizeof(gfxdevice_t)); gfxdevice_swf_init(output); /* configure device */ @@ -972,10 +1022,10 @@ int SWFOutputDev::save(char*filename) finish(); return result->save(result, filename); } -void* SWFOutputDev::getSWF() +void* SWFOutputDev::get(char*name) { finish(); - return result->get(result, "swf"); + return result->get(result, name); } SWFOutputDev::~SWFOutputDev() @@ -986,6 +1036,10 @@ SWFOutputDev::~SWFOutputDev() this->result->destroy(this->result); this->result = 0; } + + if(this->pages) { + free(this->pages); this->pages = 0; + } fontlist_t*l = this->fontlist; while(l) { @@ -1128,8 +1182,10 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, { int render = state->getRender(); // check for invisible text -- this is used by Acrobat Capture - if (render == 3) + if (render == 3) { + msg(" Ignoring invisible text: char %d at %f,%f", c, x, y); return; + } if(states[statepos].textRender != render) msg(" Internal error: drawChar.render!=beginString.render"); @@ -1173,8 +1229,9 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, Gfx8BitFont*font8; font8 = (Gfx8BitFont*)font; char**enc=font8->getEncoding(); - if(enc && enc[c]) + if(enc && enc[c] && strcasecmp(enc[c], "space")) { name = enc[c]; + } } if (CIDToGIDMap) { msg(" drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render); @@ -1183,9 +1240,27 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\" render=%d\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name), render); } - int charid = getGfxCharID(current_gfxfont, c, name, u); + int charid = -1; + + if(uLen<=1) { + charid = getGfxCharID(current_gfxfont, c, name, u); + } else { + charid = getGfxCharID(current_gfxfont, c, 0, -1); + if(charid < 0) { + /* multiple unicodes- should usually map to a ligature. + if the ligature doesn't exist, we need to draw + the characters one-by-one. */ + int t; + msg(" ligature %d missing in font %s\n", c, current_font_id); + for(t=0;t Didn't find character '%s' (c=%d,u=%d) in current charset (%s, %d characters)", FIXNULL(name),c, u, FIXNULL((char*)current_font_id), current_gfxfont->num_glyphs); } @@ -1452,7 +1527,8 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) } else if(strstr(s, "last") || strstr(s, "end")) { - page = pagepos>0?pages[pagepos-1]:0; + if(pages && pagepos>0) + page = pages[pagepos-1]; } else if(strstr(s, "first") || strstr(s, "top")) { @@ -1503,13 +1579,19 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) if(page>0) { int t; - for(t=0;t=0) { char buf[80]; sprintf(buf, "page%d", t); output->drawlink(output, points, buf); + } else { + msg(" Invalid link to page %d", page); } } else if(url) @@ -1842,7 +1924,7 @@ char* searchForSuitableFont(GfxFont*gfxFont) char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname) { char*fontname = 0, *filename = 0; - msg(" subsituteFont(%s)", oldname); + msg(" substituteFont(%s)", oldname); if(!(fontname = searchForSuitableFont(gfxFont))) { fontname = "Times-Roman"; @@ -1925,8 +2007,11 @@ int SWFOutputDev::setGfxFont(char*id, char*filename, double maxSize) we have to divide 0.05 by (fontsize/1024) */ double quality = (1024 * 0.05) / maxSize; - + + msg(" Loading %s...", filename); font = gfxfont_load(filename, quality); + msg(" Font %s loaded successfully", filename); + l = new fontlist_t; l->font = font; l->filename = strdup(filename); @@ -2019,7 +2104,12 @@ void SWFOutputDev::updateFont(GfxState *state) if(!fileName) { char * fontname = getFontName(gfxFont); msg(" Font %s %scould not be loaded.", fontname, embedded?"":"(not embedded) "); - msg(" Try putting a TTF version of that font (named \"%s.ttf\") into /swftools/fonts", fontname); + + if(lastfontdir) + msg(" Try putting a TTF version of that font (named \"%s.ttf\") into %s", fontname, lastfontdir); + else + msg(" Try specifying one or more font directories"); + fileName = substituteFont(gfxFont, fontid); if(fontid) { free(fontid);fontid = strdup(substitutetarget[substitutepos-1]); /*ugly hack*/}; msg(" Font is now %s (%s)", fontid, fileName); @@ -2045,6 +2135,8 @@ void SWFOutputDev::updateFont(GfxState *state) if(fileName) free(fileName); free(fontid); + + msg(" |"); } #define SQR(x) ((x)*(x)) @@ -2100,13 +2192,13 @@ unsigned char* antialize(unsigned char*data, int width, int height, int newwidth #define IMAGE_TYPE_JPEG 0 #define IMAGE_TYPE_LOSSLESS 1 -static void drawimage(gfxdevice_t*dev, RGBA* data, int sizex,int sizey, +static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, int sizex,int sizey, double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4, int type) { - RGBA*newpic=0; + gfxcolor_t*newpic=0; double l1 = sqrt((x4-x1)*(x4-x1) + (y4-y1)*(y4-y1)); double l2 = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); @@ -2151,13 +2243,13 @@ static void drawimage(gfxdevice_t*dev, RGBA* data, int sizex,int sizey, dev->fillbitmap(dev, &p1, &img, &m, 0); } -void drawimagejpeg(gfxdevice_t*dev, RGBA*mem, int sizex,int sizey, +void drawimagejpeg(gfxdevice_t*dev, gfxcolor_t*mem, int sizex,int sizey, double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4) { drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_JPEG); } -void drawimagelossless(gfxdevice_t*dev, RGBA*mem, int sizex,int sizey, +void drawimagelossless(gfxdevice_t*dev, gfxcolor_t*mem, int sizex,int sizey, double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4) { drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_LOSSLESS); @@ -2221,7 +2313,7 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, unsigned char buf[8]; int x,y; unsigned char*pic = new unsigned char[width*height]; - RGBA pal[256]; + gfxcolor_t pal[256]; GfxRGB rgb; state->getFillRGB(&rgb); @@ -2272,14 +2364,14 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, float r = 255/(numpalette-1); int t; for(t=0;tgetNumPixelComps()!=1 || str->getKind()==strDCT) { - RGBA*pic=new RGBA[width*height]; + gfxcolor_t*pic=new gfxcolor_t[width*height]; for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { imgStr->getPixel(pixBuf); colorMap->getRGB(pixBuf, &rgb); - pic[width*y+x].r = (U8)(rgb.r * 255 + 0.5); - pic[width*y+x].g = (U8)(rgb.g * 255 + 0.5); - pic[width*y+x].b = (U8)(rgb.b * 255 + 0.5); + pic[width*y+x].r = (unsigned char)(rgb.r * 255 + 0.5); + pic[width*y+x].g = (unsigned char)(rgb.g * 255 + 0.5); + pic[width*y+x].b = (unsigned char)(rgb.b * 255 + 0.5); pic[width*y+x].a = 255;//(U8)(rgb.a * 255 + 0.5); } } @@ -2314,8 +2406,8 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, delete imgStr; return; } else { - RGBA*pic=new RGBA[width*height]; - RGBA pal[256]; + gfxcolor_t*pic=new gfxcolor_t[width*height]; + gfxcolor_t pal[256]; int t; for(t=0;t<256;t++) { pixBuf[0] = t; @@ -2341,9 +2433,9 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pal[t].a = 0; } } else*/ { - pal[t].r = (U8)(rgb.r * 255 + 0.5); - pal[t].g = (U8)(rgb.g * 255 + 0.5); - pal[t].b = (U8)(rgb.b * 255 + 0.5); + pal[t].r = (unsigned char)(rgb.r * 255 + 0.5); + pal[t].g = (unsigned char)(rgb.g * 255 + 0.5); + pal[t].b = (unsigned char)(rgb.b * 255 + 0.5); pal[t].a = 255;//(U8)(rgb.b * 255 + 0.5); } } @@ -2532,6 +2624,7 @@ void pdfswf_addfontdir(char*dirname) { #ifdef HAVE_DIRENT_H msg(" Adding %s to font directories", dirname); + lastfontdir = strdup(dirname); DIR*dir = opendir(dirname); if(!dir) { msg(" Couldn't open directory %s\n", dirname); @@ -2668,22 +2761,6 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword) return pdf_doc; } -static void pdfswf_preparepage(int page) -{ - /*FIXME*/ - if(!pages) { - pages = (int*)malloc(1024*sizeof(int)); - pagebuflen = 1024; - } else { - if(pagepos == pagebuflen) - { - pagebuflen+=1024; - pages = (int*)realloc(pages, pagebuflen); - } - } - pages[pagepos++] = page; -} - class MemCheck { public: ~MemCheck() @@ -2700,8 +2777,6 @@ void pdf_destroy(pdf_doc_t*pdf_doc) delete i->doc; i->doc=0; - free(pages); pages = 0; //FIXME - if(i->info) { delete i->info;i->info=0; } @@ -2763,6 +2838,32 @@ void swf_output_endframe(swf_output_t*swf) i->outputDev->endframe(); } +void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage) +{ + swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; + SWFOutputDev*o = i->outputDev; + + if(pdfpage < 0) + return; + + if(!o->pages) { + o->pagebuflen = 1024; + o->pages = (int*)malloc(o->pagebuflen*sizeof(int)); + memset(o->pages, -1, o->pagebuflen*sizeof(int)); + } else { + while(pdfpage >= o->pagebuflen) + { + int oldlen = o->pagebuflen; + o->pagebuflen+=1024; + o->pages = (int*)realloc(o->pages, o->pagebuflen*sizeof(int)); + memset(&o->pages[oldlen], -1, (o->pagebuflen-oldlen)*sizeof(int)); + } + } + o->pages[pdfpage] = outputpage; + if(pdfpage>o->pagepos) + o->pagepos = pdfpage; +} + int swf_output_save(swf_output_t*swf, char*filename) { swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; @@ -2770,10 +2871,10 @@ int swf_output_save(swf_output_t*swf, char*filename) return ret; } -void* swf_output_get(swf_output_t*swf) +void* swf_output_get(swf_output_t*swf,char*name) { swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; - void* ret = i->outputDev->getSWF(); + void* ret = i->outputDev->get(name); return ret; }