X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FGFXOutputDev.cc;h=3d56d1c2d2c4537ddb36bd5976589b2e03ccb1f1;hb=f3445b49b3014b0685646d87686672fb382f2ad7;hp=eca4d9fa2fbe15174f2b129d31d033721d4d895e;hpb=8574d9999b332a2d3377d7fad4694a5e7d0ff059;p=swftools.git diff --git a/lib/pdf/GFXOutputDev.cc b/lib/pdf/GFXOutputDev.cc index eca4d9f..3d56d1c 100644 --- a/lib/pdf/GFXOutputDev.cc +++ b/lib/pdf/GFXOutputDev.cc @@ -22,7 +22,9 @@ #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include "../../config.h" #include "../os.h" #ifdef HAVE_DIRENT_H @@ -31,9 +33,6 @@ #ifdef HAVE_SYS_STAT_H #include #endif -#ifdef HAVE_FONTCONFIG -#include -#endif //xpdf header files #include "config.h" #include "gfile.h" @@ -60,7 +59,7 @@ #include "GHash.h" #include "GFXOutputDev.h" -//swftools header files +// swftools header files #include "../log.h" #include "../gfxdevice.h" #include "../gfxtools.h" @@ -71,7 +70,7 @@ #include "../devices/render.h" #include "../art/libart.h" -#include "../devices/artsutils.c" +#include "../devices/artsutils.h" #include "../png.h" #include "fonts.h" @@ -81,11 +80,16 @@ typedef struct _fontfile { const char*filename; + int len; // basename length int used; + struct _fontfile*next; } fontfile_t; // for pdfswf_addfont -static fontfile_t fonts[2048]; + +static fontfile_t* global_fonts = 0; +static fontfile_t* global_fonts_next = 0; + static int fontnum = 0; /* config */ @@ -328,18 +332,34 @@ DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName) return dfp; } } - for(t=0;tt1.fileName = new GString(fonts[t].filename); - return dfp; - } + + int bestlen = 0x7fffffff; + const char*bestfilename = 0; + + fontfile_t*f = 0; + while(f) { + if(strstr(f->filename, name)) { + if(f->len < bestlen) { + bestlen = f->len; + bestfilename = f->filename; + } + } + f = f->next; + } + if(bestfilename) { + DisplayFontParam *dfp = new DisplayFontParam(new GString(fontName), displayFontT1); + dfp->t1.fileName = new GString(bestfilename); + return dfp; } return GlobalParams::getDisplayFont(fontName); } -GFXOutputDev::GFXOutputDev(parameter_t*p) +GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) { + this->info = info; + this->doc = doc; + this->xref = doc->getXRef(); + this->jpeginfo = 0; this->textmodeinfo = 0; this->linkinfo = 0; @@ -363,52 +383,45 @@ GFXOutputDev::GFXOutputDev(parameter_t*p) this->pages = 0; this->pagebuflen = 0; this->pagepos = 0; - this->config_use_fontconfig=1; this->config_break_on_warning=0; this->config_remapunicode=0; this->config_transparent=0; this->config_extrafontdata = 0; + this->config_fontquality = 10; - this->parameters = p; - this->gfxfontlist = gfxfontlist_create(); memset(states, 0, sizeof(states)); - - /* configure device */ - while(p) { - setParameter(p->name, p->value); - p = p->next; - } }; void GFXOutputDev::setParameter(const char*key, const char*value) { if(!strcmp(key,"breakonwarning")) { this->config_break_on_warning = atoi(value); - } else if(!strcmp(key,"fontconfig")) { - this->config_use_fontconfig = atoi(value); } else if(!strcmp(key,"remapunicode")) { this->config_remapunicode = atoi(value); } else if(!strcmp(key,"transparent")) { this->config_transparent = atoi(value); } else if(!strcmp(key,"extrafontdata")) { this->config_extrafontdata = atoi(value); + } else if(!strcmp(key,"fontquality")) { + this->config_fontquality = atof(value); + if(this->config_fontquality<=1) + this->config_fontquality=1; + } else if(!strcmp(key,"help")) { + printf("\nPDF layer options:\n"); + printf("breakonwarning=0/1 Abort conversion if graphic objects are found which\n"); + printf(" are not 100%% supported\n"); + printf("transparent=0/1 Make PDF transparent (alpha background)\n"); + printf("extrafontdata=0/1 Store Type3 characters and capture characters\n"); + printf("fontquality=1..100 Curve approximation quality of the fonts\n"); } + } void GFXOutputDev::setDevice(gfxdevice_t*dev) { - parameter_t*p = this->parameters; - - /* pass parameters to output device */ this->device = dev; - if(this->device) { - while(p) { - this->device->setparameter(this->device, p->name, p->value); - p = p->next; - } - } } void GFXOutputDev::setMove(int x,int y) @@ -656,7 +669,11 @@ GBool GFXOutputDev::needNonText() } void GFXOutputDev::endPage() { - msg(" endPage"); + msg(" endPage (GfxOutputDev)"); + if(outer_clip_box) { + device->endclip(device); + outer_clip_box = 0; + } } #define STROKE_FILL 1 @@ -703,7 +720,7 @@ void GFXOutputDev::strokeGfxline(GfxState *state, gfxline_t*line, int flags) msg(" %d dashes", dashnum); msg(" | phase: %f", dashphase); for(t=0;t | d%-3d: %f", t, ldash[t]); } dash[dashnum] = -1; @@ -711,7 +728,7 @@ void GFXOutputDev::strokeGfxline(GfxState *state, gfxline_t*line, int flags) dump_outline(line); } - line2 = gfxtool_dash_line(line, dash, dashphase); + line2 = gfxtool_dash_line(line, dash, (float)dashphase); line = line2; free(dash); msg(" After dashing:"); @@ -826,14 +843,6 @@ void GFXOutputDev::clipToStrokePath(GfxState *state) gfxline_free(line); } -void GFXOutputDev::endframe() -{ - if(outer_clip_box) { - device->endclip(device); - outer_clip_box = 0; - } -} - void GFXOutputDev::finish() { if(outer_clip_box) { @@ -852,7 +861,7 @@ GFXOutputDev::~GFXOutputDev() free(this->pages); this->pages = 0; } - gfxfontlist_free(this->gfxfontlist); + gfxfontlist_free(this->gfxfontlist, 1);this->gfxfontlist = 0; }; GBool GFXOutputDev::upsideDown() { @@ -866,12 +875,6 @@ GBool GFXOutputDev::useDrawChar() const char*renderModeDesc[]= {"fill", "stroke", "fill+stroke", "invisible", "clip+fill", "stroke+clip", "fill+stroke+clip", "clip"}; -#define RENDER_FILL 0 -#define RENDER_STROKE 1 -#define RENDER_FILLSTROKE 2 -#define RENDER_INVISIBLE 3 -#define RENDER_CLIP 4 - static char tmp_printstr[4096]; char* makeStringPrintable(char*str) { @@ -953,7 +956,7 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y, CharCode charid, int nBytes, Unicode *_u, int uLen) { if(!current_fontinfo || (unsigned)charid >= current_fontinfo->num_glyphs || !current_fontinfo->glyphs[charid]) { - msg(" Invalid charid %d for font %s", charid, current_font_id); + msg(" Invalid charid %d for font (%d characters)", charid, current_fontinfo?current_fontinfo->num_glyphs:0); return; } @@ -965,6 +968,8 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y, // check for invisible text -- this is used by Acrobat Capture if (render == RENDER_INVISIBLE) { col.a = 0; + if(!config_extrafontdata) + return; } GfxFont*font = state->getFont(); @@ -1082,7 +1087,7 @@ GBool GFXOutputDev::beginType3Char(GfxState *state, double x, double y, double d m.ty += user_movey + clipmovey; if(!current_fontinfo || (unsigned)charid >= current_fontinfo->num_glyphs || !current_fontinfo->glyphs[charid]) { - msg(" Invalid charid %d for font %s", charid, current_font_id); + msg(" Invalid charid %d for font", charid); return gFalse; } gfxcolor_t col={0,0,0,0}; @@ -1106,29 +1111,16 @@ void GFXOutputDev::endType3Char(GfxState *state) msg(" endType3Char"); } -void GFXOutputDev::startFrame(int width, int height) -{ - if(outer_clip_box) { - device->endclip(device); - outer_clip_box = 0; - } - - device->startpage(device, width, height); - this->width = width; - this->height = height; -} - void GFXOutputDev::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; + gfxcolor_t white = {255,255,255,255}; + gfxcolor_t black = {255,0,0,0}; laststate = state; 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); Use CropBox, not MediaBox, as page size @@ -1176,7 +1168,7 @@ void GFXOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl void GFXOutputDev::processLink(Link *link, Catalog *catalog) { - double x1, y1, x2, y2, w; + double x1, y1, x2, y2; gfxline_t points[5]; int x, y; @@ -1214,6 +1206,10 @@ void GFXOutputDev::processLink(Link *link, Catalog *catalog) points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y); + + if(getLogLevel() >= LOGLEVEL_TRACE) { + dump_outline(points); + } LinkAction*action=link->getAction(); char buf[128]; @@ -1450,13 +1446,8 @@ void GFXOutputDev::updateStrokeColor(GfxState *state) state->getStrokeRGB(&rgb); } -void GFXOutputDev::setXRef(PDFDoc*doc, XRef *xref) -{ - this->doc = doc; - this->xref = xref; -} -gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src) +gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src, double config_fontquality) { gfxfont_t*font = (gfxfont_t*)malloc(sizeof(gfxfont_t)); memset(font, 0, sizeof(gfxfont_t)); @@ -1465,7 +1456,8 @@ gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src) memset(font->glyphs, 0, sizeof(gfxglyph_t)*src->num_glyphs); font->id = strdup(getFontID(xpdffont)); int t; - double quality = (INTERNAL_FONT_SIZE * 0.05) / src->max_size; + + double quality = (INTERNAL_FONT_SIZE * 200 / config_fontquality) / src->max_size; double scale = 1; //printf("%d glyphs\n", font->num_glyphs); font->num_glyphs = 0; @@ -1547,14 +1539,19 @@ void GFXOutputDev::updateFont(GfxState *state) } this->current_fontinfo = this->info->getFont(id); + if(!this->current_fontinfo) { + msg(" Internal Error: no fontinfo for font %s\n", id); + return; + } if(!this->current_fontinfo->seen) { dumpFontInfo("", gfxFont); } gfxfont_t*font = gfxfontlist_findfont(this->gfxfontlist,id); if(!font) { - font = createGfxFont(gfxFont, current_fontinfo); - gfxfontlist_addfont(this->gfxfontlist, font); + font = createGfxFont(gfxFont, current_fontinfo, this->config_fontquality); + font->id = strdup(id); + this->gfxfontlist = gfxfontlist_addfont(this->gfxfontlist, font); device->addfont(device, font); } current_gfxfont = font; @@ -1573,7 +1570,6 @@ unsigned char* antialize(unsigned char*data, int width, int height, int newwidth unsigned char*newdata; int x,y; newdata= (unsigned char*)malloc(newwidth*newheight); - int t; double fx = (double)(width)/newwidth; double fy = (double)(height)/newheight; double px = 0; @@ -1646,9 +1642,6 @@ static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, int sizex,int sizey, p5.y = (int)(p5.y*20)/20.0; } - float m00,m10,tx; - float m01,m11,ty; - gfxmatrix_t m; m.m00 = (p4.x-p1.x)/sizex; m.m10 = (p2.x-p1.x)/sizey; m.m01 = (p4.y-p1.y)/sizex; m.m11 = (p2.y-p1.y)/sizey; @@ -1773,7 +1766,6 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, } if(mask) { - int i,j; unsigned char buf[8]; int x,y; unsigned char*pic = new unsigned char[width*height]; @@ -1802,7 +1794,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, /* the size of the drawn image is added to the identifier as the same image may require different bitmaps if displayed at different sizes (due to antialiasing): */ - int t,found = -1; + int found = -1; if(type3active) { unsigned char*pic2 = 0; numpalette = 16; @@ -1810,7 +1802,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pic2 = antialize(pic,width,height,realwidth,realheight,numpalette); if(!pic2) { - delete pic; + delete[] pic; delete imgStr; return; } @@ -1822,7 +1814,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, /* make a black/white palette */ - float r = 255/(numpalette-1); + float r = 255./(float)(numpalette-1); int t; for(t=0;t Adding font \"%s\".", filename); - fonts[fontnum++] = f; + fontfile_t* f = (fontfile_t*)malloc(sizeof(fontfile_t)); + memset(f, 0, sizeof(fontfile_t)); + f->filename = filename; + int len = strlen(filename); + char*r1 = strrchr(filename, '/'); + char*r2 = strrchr(filename, '\\'); + if(r2>r1) + r1 = r2; + if(r1) { + len = strlen(r1+1); + } + f->len = len; + + msg(" Adding font \"%s\".", filename); + if(global_fonts_next) { + global_fonts_next->next = f; + global_fonts_next = global_fonts_next->next; } else { - msg(" Too many external fonts. Not adding font file \"%s\".", filename); + global_fonts_next = global_fonts = f; } } @@ -2048,7 +2051,6 @@ void addGlobalLanguageDir(const char*dir) { msg(" Adding %s to language pack directories", dir); - int l; FILE*fi = 0; char* config_file = (char*)malloc(strlen(dir) + 1 + sizeof("add-to-xpdfrc") + 1); strcpy(config_file, dir); @@ -2102,7 +2104,7 @@ void addGlobalFontDir(const char*dirname) } closedir(dir); #else - msg(" No dirent.h- unable to add font dir %s", dir); + msg(" No dirent.h- unable to add font dir %s", dirname); #endif } @@ -2216,16 +2218,15 @@ void GFXOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, GBool forSoftMask) { const char*colormodename = ""; - BBox rect = mkBBox(state, bbox, this->width, this->height); if(blendingColorSpace) { colormodename = GfxColorSpace::getColorSpaceModeName(blendingColorSpace->getMode()); } dbg("beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask); - dbg("using clipping rect %f/%f/%f/%f\n", rect.posx,rect.posy,rect.width,rect.height); msg(" beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask); - states[statepos].createsoftmask |= forSoftMask; + //states[statepos].createsoftmask |= forSoftMask; + states[statepos].createsoftmask = forSoftMask; states[statepos].transparencygroup = !forSoftMask; states[statepos].isolated = isolated; @@ -2250,10 +2251,11 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state) this->device = states[statepos].olddevice; + gfxresult_t*recording = r->finish(r); if(states[statepos].createsoftmask) { - states[statepos-1].softmaskrecording = r->finish(r); + states[statepos-1].softmaskrecording = recording; } else { - states[statepos-1].grouprecording = r->finish(r); + states[statepos-1].grouprecording = recording; } states[statepos].createsoftmask = 0;