X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;ds=sidebyside;f=pdf2swf%2FSWFOutputDev.cc;h=5ce505ded8197af80c1d8e09caec108573b62a96;hb=b38cd8adf9bee8bb1ed1f1f19b1cb0063196750f;hp=e24686744a6be8d55ac944341363a7cae6bca99f;hpb=1501d0d231cf685584890de158e5d361c16b0c0e;p=swftools.git diff --git a/pdf2swf/SWFOutputDev.cc b/pdf2swf/SWFOutputDev.cc index e246867..5ce505d 100644 --- a/pdf2swf/SWFOutputDev.cc +++ b/pdf2swf/SWFOutputDev.cc @@ -144,7 +144,6 @@ typedef struct _fontlist } fontlist_t; class SWFOutputDev: public OutputDev { - int outputstarted; public: gfxdevice_t* output; @@ -158,10 +157,14 @@ public: void setClip(int x1,int y1,int x2,int y2); int save(char*filename); - void pagefeed(); - void* getSWF(); + + // Start a page. + void startFrame(int width, int height); + + virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ; - void getDimensions(int*x1,int*y1,int*x2,int*y2); + void endframe(); + void* getSWF(); //----- get info about output device @@ -181,9 +184,6 @@ public: void setXRef(PDFDoc*doc, XRef *xref); - // Start a page. - virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ; - //----- link borders virtual void drawLink(Link *link, Catalog *catalog) ; @@ -253,7 +253,9 @@ public: void finish(); - SWF*swf; //filled upon completion + gfxresult_t*result; //filled when complete + + char outer_clip_box; //whether the page clip box is still on SWFOutputState states[64]; int statepos; @@ -267,6 +269,7 @@ public: char* substituteFont(GfxFont*gfxFont, char*oldname); char* writeEmbeddedFontToFile(XRef*ref, GfxFont*font); int t1id; + int textmodeinfo; // did we write "Text will be rendered as polygon" yet? int jpeginfo; // did we write "File contains jpegs" yet? int pbminfo; // did we write "File contains jpegs" yet? int linkinfo; // did we write "File contains links" yet? @@ -360,12 +363,12 @@ class InfoOutputDev: public OutputDev SWFOutputDev::SWFOutputDev() { jpeginfo = 0; + textmodeinfo = 0; ttfinfo = 0; linkinfo = 0; pbminfo = 0; type3active = 0; statepos = 0; - outputstarted = 0; xref = 0; substitutepos = 0; type3Warning = 0; @@ -378,9 +381,16 @@ SWFOutputDev::SWFOutputDev() current_text_stroke = 0; current_text_clip = 0; fontlist = 0; - swf = 0; + result = 0; + outer_clip_box = 0; output = (gfxdevice_t*)malloc(sizeof(gfxdevice_t)); - memset(output, 0, sizeof(output)); + gfxdevice_swf_init(output); + /* configure device */ + parameter_t*p = device_config; + while(p) { + output->setparameter(output, p->name, p->value); + p = p->next; + } }; void SWFOutputDev::setMove(int x,int y) @@ -399,10 +409,6 @@ void SWFOutputDev::setClip(int x1,int y1,int x2,int y2) this->user_clipx2 = x2; this->user_clipy2 = y2; } -void SWFOutputDev::getDimensions(int*x1,int*y1,int*x2,int*y2) -{ - return gfxdevice_swf_getdimensions(output, x1,y1,x2,y2); -} static char*getFontID(GfxFont*font) { @@ -648,7 +654,7 @@ void dump_outline(gfxline_t*line) } } -gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed) +gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed, int user_movex, int user_movey) { int num = path->getNumSubpaths(); int s,t; @@ -669,7 +675,11 @@ gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed) for(s=0;stransform(subpath->getX(s),subpath->getY(s),&x,&y); + x += user_movex; + y += user_movey; + if(s==0) { if(closed && needsfix && (fabs(posx-lastx)+fabs(posy-lasty))>0.001) { draw.lineTo(&draw, lastx, lasty); @@ -715,7 +725,7 @@ gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed) void SWFOutputDev::stroke(GfxState *state) { GfxPath * path = state->getPath(); - gfxline_t*line= gfxPath_to_gfxline(state, path, 0); + gfxline_t*line= gfxPath_to_gfxline(state, path, 0, user_movex, user_movey); strokeGfxline(state, line); gfxline_free(line); } @@ -774,6 +784,7 @@ void SWFOutputDev::strokeGfxline(GfxState *state, gfxline_t*line) line2 = gfxtool_dash_line(line, dash, dashphase); line = line2; + free(dash); msg(" After dashing:"); } @@ -824,7 +835,7 @@ void SWFOutputDev::fillGfxLine(GfxState *state, gfxline_t*line) void SWFOutputDev::fill(GfxState *state) { GfxPath * path = state->getPath(); - gfxline_t*line= gfxPath_to_gfxline(state, path, 1); + gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex, user_movey); fillGfxLine(state, line); gfxline_free(line); } @@ -833,7 +844,7 @@ void SWFOutputDev::eoFill(GfxState *state) GfxPath * path = state->getPath(); gfxcolor_t col = getFillColor(state); - gfxline_t*line= gfxPath_to_gfxline(state, path, 1); + gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex, user_movey); if(getLogLevel() >= LOGLEVEL_TRACE) { msg(" eofill\n"); @@ -847,7 +858,7 @@ void SWFOutputDev::eoFill(GfxState *state) void SWFOutputDev::clip(GfxState *state) { GfxPath * path = state->getPath(); - gfxline_t*line = gfxPath_to_gfxline(state, path, 1); + gfxline_t*line = gfxPath_to_gfxline(state, path, 1, user_movex, user_movey); clipToGfxLine(state, line); gfxline_free(line); } @@ -865,7 +876,7 @@ void SWFOutputDev::clipToGfxLine(GfxState *state, gfxline_t*line) void SWFOutputDev::eoClip(GfxState *state) { GfxPath * path = state->getPath(); - gfxline_t*line = gfxPath_to_gfxline(state, path, 1); + gfxline_t*line = gfxPath_to_gfxline(state, path, 1, user_movex, user_movey); if(getLogLevel() >= LOGLEVEL_TRACE) { msg(" eoclip\n"); @@ -877,37 +888,48 @@ void SWFOutputDev::eoClip(GfxState *state) gfxline_free(line); } -/* pass through functions for swf_output */ -int SWFOutputDev::save(char*filename) +void SWFOutputDev::endframe() { - return gfxdevice_swf_save(output, filename); -} -void SWFOutputDev::pagefeed() -{ - swfoutput_pagefeed(output); -} -void* SWFOutputDev::getSWF() -{ - return (void*)gfxdevice_swf_get(output); + if(outer_clip_box) { + output->endclip(output); + outer_clip_box = 0; + } + + output->endpage(output); } void SWFOutputDev::finish() { + if(outer_clip_box) { + if(output) { + output->endclip(output); + } + outer_clip_box = 0; + } if(output) { - this->swf = (SWF*)output->finish(output); + this->result = output->finish(output); free(output);output=0; } } +int SWFOutputDev::save(char*filename) +{ + finish(); + return result->save(result, filename); +} +void* SWFOutputDev::getSWF() +{ + finish(); + return result->get(result, "swf"); +} + SWFOutputDev::~SWFOutputDev() { finish(); - outputstarted = 0; - if(this->swf) { - swf_FreeTags(this->swf); - free(this->swf); - this->swf = 0; + if(this->result) { + this->result->destroy(this->result); + this->result = 0; } fontlist_t*l = this->fontlist; @@ -920,10 +942,10 @@ SWFOutputDev::~SWFOutputDev() free(l); l = next; } + this->fontlist = 0; }; GBool SWFOutputDev::upsideDown() { - msg(" upsidedown? yes"); return gTrue; }; GBool SWFOutputDev::useDrawChar() @@ -1002,6 +1024,11 @@ int getGfxCharID(gfxfont_t*font, int charnr, char *charname, int u) return font->unicode2glyph[u]; } + /* we don't need to "draw" space characters, so don't overdo the search + for a matching glyph */ + if(charname && !strcasecmp(charname, "space")) + return -1; + if(charnr>=0 && charnrnum_glyphs) { msg(" Char [>%d<,%s,%d] maps to %d\n", charnr, charname, u, charnr); return charnr; @@ -1103,18 +1130,26 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, int charid = getGfxCharID(current_gfxfont, c, name, u); if(charid<0) { - msg(" 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); + if(strcasecmp(name, "space")) { + msg(" 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); + } return; } gfxmatrix_t m = this->current_font_matrix; state->transform(x, y, &m.tx, &m.ty); + m.tx += user_movex; + m.ty += user_movey; if(render == RENDER_FILL) { output->drawchar(output, current_font_id, charid, &col, &m); } else { msg(" Drawing glyph %d as shape", charid); + if(!textmodeinfo) { + msg(" Some texts will be rendered as shape"); + textmodeinfo = 1; + } gfxline_t*glyph = current_gfxfont->glyphs[charid].line; gfxline_t*tglyph = gfxline_clone(glyph); gfxline_transform(tglyph, &m); @@ -1206,15 +1241,21 @@ void SWFOutputDev::endType3Char(GfxState *state) msg(" endType3Char"); } +void SWFOutputDev::startFrame(int width, int height) +{ + output->startpage(output, width, height); +} + void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2) { this->currentpage = pageNum; double x1,y1,x2,y2; int rot = doc->getPageRotate(1); + gfxcolor_t white; laststate = state; - msg(" startPage %d (%f,%f,%f,%f)\n", pageNum, crop_x1, crop_y1, crop_x2, crop_y2); - if(rot!=0) - msg(" page is rotated %d degrees\n", rot); + gfxline_t clippath[5]; + + white.r = white.g = white.b = white.a = 255; /* state->transform(state->getX1(),state->getY1(),&x1,&y1); state->transform(state->getX2(),state->getY2(),&x2,&y2); @@ -1225,12 +1266,13 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl y1 = crop_y1; x2 = crop_x2; y2 = crop_y2;*/ - state->transform(crop_x1,crop_y1,&x1,&y1); - state->transform(crop_x2,crop_y2,&x2,&y2); + state->transform(crop_x1,crop_y1,&x1,&y1); //x1 += user_movex; y1 += user_movey; + state->transform(crop_x2,crop_y2,&x2,&y2); //x2 += user_movex; y2 += user_movey; if(x2 x1)*/ x1 = user_clipx1; @@ -1239,22 +1281,24 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl /*if(user_clipy2 < y2)*/ y2 = user_clipy2; } - if(!outputstarted) { - msg(" Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2); - - gfxdevice_swf_init(output); - - /* configure device */ - parameter_t*p = device_config; - while(p) { - output->setparameter(output, p->name, p->value); - p = p->next; - } - - outputstarted = 1; + //msg(" Bounding box is (%f,%f)-(%f,%f) [shifted by %d/%d]", x1,y1,x2,y2, user_movex, user_movey); + + if(outer_clip_box) { + output->endclip(output); + outer_clip_box = 0; } - - swfoutput_newpage(output, pageNum, user_movex, user_movey, (int)x1, (int)y1, (int)x2, (int)y2); + + msg(" processing PDF page %d (%dx%d:%d:%d) (move:%d:%d)", pageNum, (int)x2-(int)x1,(int)y2-(int)y1, (int)x1, (int)y1, user_movex, user_movey); + if(rot!=0) + msg(" page is rotated %d degrees\n", rot); + + clippath[0].type = gfx_moveTo;clippath[0].x = x1; clippath[0].y = y1; clippath[0].next = &clippath[1]; + clippath[1].type = gfx_lineTo;clippath[1].x = x2; clippath[1].y = y1; clippath[1].next = &clippath[2]; + clippath[2].type = gfx_lineTo;clippath[2].x = x2; clippath[2].y = y2; clippath[2].next = &clippath[3]; + clippath[3].type = gfx_lineTo;clippath[3].x = x1; clippath[3].y = y2; clippath[3].next = &clippath[4]; + clippath[4].type = gfx_lineTo;clippath[4].x = x1; clippath[4].y = y1; clippath[4].next = 0; + output->startclip(output, clippath); outer_clip_box = 1; + output->fill(output, clippath, &white); } void SWFOutputDev::drawLink(Link *link, Catalog *catalog) @@ -1275,28 +1319,28 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog) rgb.b = 1; cvtUserToDev(x1, y1, &x, &y); points[0].type = gfx_moveTo; - points[0].x = points[4].x = (int)x; - points[0].y = points[4].y = (int)y; + points[0].x = points[4].x = x + user_movex; + points[0].y = points[4].y = y + user_movey; points[0].next = &points[1]; cvtUserToDev(x2, y1, &x, &y); points[1].type = gfx_lineTo; - points[1].x = (int)x; - points[1].y = (int)y; + points[1].x = x + user_movex; + points[1].y = y + user_movey; points[1].next = &points[2]; cvtUserToDev(x2, y2, &x, &y); points[2].type = gfx_lineTo; - points[2].x = (int)x; - points[2].y = (int)y; + points[2].x = x + user_movex; + points[2].y = y + user_movey; points[2].next = &points[3]; cvtUserToDev(x1, y2, &x, &y); points[3].type = gfx_lineTo; - points[3].x = (int)x; - points[3].y = (int)y; + points[3].x = x + user_movex; + points[3].y = y + user_movey; points[3].next = &points[4]; cvtUserToDev(x1, y1, &x, &y); points[4].type = gfx_lineTo; - points[4].x = (int)x; - points[4].y = (int)y; + points[4].x = x + user_movex; + points[4].y = y + user_movey; points[4].next = 0; LinkAction*action=link->getAction(); @@ -1903,6 +1947,7 @@ void SWFOutputDev::updateFont(GfxState *state) char * fontname = getFontName(gfxFont); fileName = searchFont(fontname); if(!fileName) showFontError(gfxFont,0); + free(fontname); } if(!fileName) { char * fontname = getFontName(gfxFont); @@ -2086,10 +2131,10 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, return; } - state->transform(0, 1, &x1, &y1); - state->transform(0, 0, &x2, &y2); - state->transform(1, 0, &x3, &y3); - state->transform(1, 1, &x4, &y4); + state->transform(0, 1, &x1, &y1); x1 += user_movex; y1+= user_movey; + state->transform(0, 0, &x2, &y2); x2 += user_movex; y2+= user_movey; + state->transform(1, 0, &x3, &y3); x3 += user_movex; y3+= user_movey; + state->transform(1, 1, &x4, &y4); x4 += user_movex; y4+= user_movey; if(!pbminfo && !(str->getKind()==strDCT)) { if(!type3active) { @@ -2544,7 +2589,7 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword) return pdf_doc; } -void pdfswf_preparepage(int page) +static void pdfswf_preparepage(int page) { /*FIXME*/ if(!pages) { @@ -2574,7 +2619,6 @@ void pdf_destroy(pdf_doc_t*pdf_doc) { pdf_doc_internal_t*i= (pdf_doc_internal_t*)pdf_doc->internal; - msg(" pdfswf.cc: pdfswf_close()"); delete i->doc; i->doc=0; free(pages); pages = 0; //FIXME @@ -2619,24 +2663,27 @@ swf_output_t* swf_output_init() return swf_output; } -void swf_output_setparameter(swf_output_t*swf_output, char*name, char*value) +void swf_output_setparameter(swf_output_t*swf, char*name, char*value) { - /* FIXME */ pdfswf_setparameter(name, value); } -void swf_output_pagefeed(swf_output_t*swf) +void swf_output_startframe(swf_output_t*swf, int width, int height) +{ + swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; + i->outputDev->startFrame(width, height); +} + +void swf_output_endframe(swf_output_t*swf) { swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; - i->outputDev->pagefeed(); - i->outputDev->getDimensions(&swf->x1, &swf->y1, &swf->x2, &swf->y2); + i->outputDev->endframe(); } int swf_output_save(swf_output_t*swf, char*filename) { swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; int ret = i->outputDev->save(filename); - i->outputDev->getDimensions(&swf->x1, &swf->y1, &swf->x2, &swf->y2); return ret; } @@ -2644,7 +2691,6 @@ void* swf_output_get(swf_output_t*swf) { swf_output_internal_t*i= (swf_output_internal_t*)swf->internal; void* ret = i->outputDev->getSWF(); - i->outputDev->getDimensions(&swf->x1, &swf->y1, &swf->x2, &swf->y2); return ret; } @@ -2671,7 +2717,6 @@ void pdf_page_render2(pdf_page_t*page, swf_output_t*swf) #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)