X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FGFXOutputDev.cc;h=ef441b4ccc1acbf9e28808bca5a2fc804b2dbb41;hb=44b96036f984be2cfdf899f1d6de94230cb4c922;hp=863f46431dac083a302fd87914531970b7fd8ae6;hpb=d75c1277468b4045fc96b44bcf4ffd058744ee0f;p=swftools.git diff --git a/lib/pdf/GFXOutputDev.cc b/lib/pdf/GFXOutputDev.cc index 863f464..ef441b4 100644 --- a/lib/pdf/GFXOutputDev.cc +++ b/lib/pdf/GFXOutputDev.cc @@ -540,7 +540,7 @@ 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; @@ -564,6 +564,7 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) this->pages = 0; this->pagebuflen = 0; this->pagepos = 0; + this->config_bigchar=0; this->config_convertgradients=1; this->config_break_on_warning=0; this->config_remapunicode=0; @@ -571,8 +572,10 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) this->config_extrafontdata = 0; this->config_fontquality = 10; this->config_optimize_polygons = 0; + this->config_multiply = 1; this->gfxfontlist = gfxfontlist_create(); + this->dashPattern = 0; memset(states, 0, sizeof(states)); this->featurewarnings = 0; @@ -590,8 +593,14 @@ void GFXOutputDev::setParameter(const char*key, const char*value) this->config_extrafontdata = atoi(value); } else if(!strcmp(key,"convertgradients")) { this->config_convertgradients = atoi(value); + } else if(!strcmp(key,"multiply")) { + this->config_multiply = atoi(value); + if(this->config_multiply<1) + this->config_multiply=1; } else if(!strcmp(key,"optimize_polygons")) { this->config_optimize_polygons = atoi(value); + } else if(!strcmp(key,"bigchar")) { + this->config_bigchar = atoi(value); } else if(!strcmp(key,"fontquality")) { this->config_fontquality = atof(value); if(this->config_fontquality<=1) @@ -996,6 +1005,8 @@ GBool GFXOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) m.ty = (y0 + y1)/2 - 0.5; device->fillgradient(device, &p1, g, gfxgradient_linear, &m); + + free(g); return gTrue; } @@ -1080,6 +1091,8 @@ void GFXOutputDev::strokeGfxline(GfxState *state, gfxline_t*line, int flags) msg(" | phase: %f", this->dashStart); for(t=0;tdashLength;t++) { dash[t] = (float)this->dashPattern[t] * f; + if(!dash[t]) + dash[t] = 1e-37; msg(" | d%-3d: %f", t, this->dashPattern[t]); } dash[this->dashLength] = -1; @@ -1220,6 +1233,9 @@ GFXOutputDev::~GFXOutputDev() if(this->pages) { free(this->pages); this->pages = 0; } + if(this->dashPattern) { + free(this->dashPattern);this->dashPattern = 0; + } feature_t*f = this->featurewarnings; while(f) { @@ -1778,10 +1794,18 @@ void GFXOutputDev::restoreState(GfxState *state) { void GFXOutputDev::updateLineDash(GfxState *state) { - state->getLineDash(&this->dashPattern, &this->dashLength, &this->dashStart); + if(this->dashPattern) { + free(this->dashPattern);this->dashPattern = 0; + } + double *pattern = 0; + state->getLineDash(&pattern, &this->dashLength, &this->dashStart); msg(" updateLineDash, %d dashes", this->dashLength); if(!this->dashLength) { this->dashPattern = 0; + } else { + double*p = (double*)malloc(this->dashLength*sizeof(this->dashPattern[0])); + memcpy(p, pattern, this->dashLength*sizeof(this->dashPattern[0])); + this->dashPattern = p; } } @@ -1842,7 +1866,7 @@ void GFXOutputDev::updateStrokeColor(GfxState *state) } -static gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src, double config_fontquality) +gfxfont_t* GFXOutputDev::createGfxFont(GfxFont*xpdffont, FontInfo*src) { gfxfont_t*font = (gfxfont_t*)malloc(sizeof(gfxfont_t)); memset(font, 0, sizeof(gfxfont_t)); @@ -1851,11 +1875,14 @@ static gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src, double config_fo memset(font->glyphs, 0, sizeof(gfxglyph_t)*src->num_glyphs); font->id = 0; int t; - + 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; + font->ascent = fabs(src->descender); + font->descent = fabs(src->ascender); + for(t=0;tnum_glyphs;t++) { if(src->glyphs[t]) { SplashPath*path = src->glyphs[t]->path; @@ -1897,8 +1924,21 @@ static gfxfont_t* createGfxFont(GfxFont*xpdffont, FontInfo*src, double config_fo // (f&splashPathFirst)?"first":"", // (f&splashPathLast)?"last":""); } + glyph->line = (gfxline_t*)drawer.result(&drawer); - glyph->advance = xmax*scale; // we don't know the real advance value, so this'll have to do + if(src->glyphs[t]->advance>0) { + glyph->advance = src->glyphs[t]->advance; + } else { + msg(" Approximating advance value for glyph %d", t); + glyph->advance = xmax*scale; + } + if(this->config_bigchar) { + double max = src->glyphs[t]->advance_max; + if(max>0 && max > glyph->advance) { + glyph->advance = max; + } + } + font->num_glyphs++; } } @@ -1944,7 +1984,7 @@ void GFXOutputDev::updateFont(GfxState *state) gfxfont_t*font = gfxfontlist_findfont(this->gfxfontlist,id); if(!font) { - font = createGfxFont(gfxFont, current_fontinfo, this->config_fontquality); + font = this->createGfxFont(gfxFont, current_fontinfo); font->id = strdup(id); this->gfxfontlist = gfxfontlist_addfont(this->gfxfontlist, font); } @@ -1960,7 +2000,7 @@ void GFXOutputDev::updateFont(GfxState *state) unsigned char* antialize(unsigned char*data, int width, int height, int newwidth, int newheight, int palettesize) { - if((newwidth<2 || newheight<2) || + if((newwidth<1 || newheight<1) || (width<=newwidth || height<=newheight)) return 0; unsigned char*newdata; @@ -2016,7 +2056,7 @@ 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) + double x4,double y4, int type, int multiply) { gfxcolor_t*newpic=0; @@ -2041,12 +2081,13 @@ static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, int sizex,int sizey, p5.x = (int)(p5.x*20)/20.0; p5.y = (int)(p5.y*20)/20.0; } - + 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; - m.tx = p1.x - 0.5; - m.ty = p1.y - 0.5; + + m.tx = p1.x - 0.5*multiply; + m.ty = p1.y - 0.5*multiply; gfximage_t img; img.data = (gfxcolor_t*)data; @@ -2062,15 +2103,15 @@ static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, 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) + double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4, int multiply) { - drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_JPEG); + drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_JPEG, multiply); } 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) + double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4, int multiply) { - drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_LOSSLESS); + drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_LOSSLESS, multiply); } @@ -2079,6 +2120,8 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, GBool inlineImg, int mask, int*maskColors, Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GfxImageColorMap*maskColorMap) { + /* the code in this function is *old*. It's not pretty, but it works. */ + double x1,y1,x2,y2,x3,y3,x4,y4; ImageStream *imgStr; Guchar pixBuf[4]; @@ -2133,7 +2176,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, imgStr = new ImageStream(str, width, ncomps,bits); imgStr->reset(); - if(!width || !height || (height<=1 && width<=1 && maskWidth<=1 && maskHeight<=1)) + if(!width || !height || ((height+width)<=1 && (maskWidth+maskHeight)<=1)) { msg(" Ignoring %d by %d image", width, height); unsigned char buf[8]; @@ -2201,11 +2244,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, buf[0]=1-buf[0]; pic[width*y+x] = buf[0]; } - - /* 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 found = -1; + if(type3active) { unsigned char*pic2 = 0; numpalette = 16; @@ -2242,7 +2281,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pic2[width*y+x] = pal[pic[y*width+x]]; } } - drawimagelossless(device, pic2, width, height, x1,y1,x2,y2,x3,y3,x4,y4); + drawimagelossless(device, pic2, width, height, x1,y1,x2,y2,x3,y3,x4,y4, config_multiply); delete[] pic2; delete[] pic; delete imgStr; @@ -2263,14 +2302,30 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, pic[width*y+x].b = (unsigned char)(colToByte(rgb.b)); pic[width*y+x].a = 255;//(U8)(rgb.a * 255 + 0.5); if(maskbitmap) { - pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)]; + int x1 = x*maskWidth/width; + int y1 = y*maskHeight/height; + int x2 = (x+1)*maskWidth/width; + int y2 = (y+1)*maskHeight/height; + int xx,yy; + unsigned int alpha=0; + unsigned int count=0; + for(xx=x1;xxgetKind()==strDCT) - drawimagejpeg(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4); + drawimagejpeg(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4, config_multiply); else - drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4); + drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4, config_multiply); delete[] pic; delete imgStr; if(maskbitmap) free(maskbitmap); @@ -2345,7 +2400,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str, height = maskHeight; } } - drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4); + drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4, config_multiply); delete[] pic; delete imgStr; @@ -2557,17 +2612,20 @@ void GFXOutputDev::preparePage(int pdfpage, int outputpage) if(!this->pages) { this->pagebuflen = 1024; + if(pdfpage > this->pagebuflen) + this->pagebuflen = pdfpage+1; this->pages = (int*)malloc(this->pagebuflen*sizeof(int)); memset(this->pages, -1, this->pagebuflen*sizeof(int)); - } else { - while(pdfpage >= this->pagebuflen) - { - int oldlen = this->pagebuflen; - this->pagebuflen+=1024; - this->pages = (int*)realloc(this->pages, this->pagebuflen*sizeof(int)); - memset(&this->pages[oldlen], -1, (this->pagebuflen-oldlen)*sizeof(int)); - } } + + while(pdfpage >= this->pagebuflen) + { + int oldlen = this->pagebuflen; + this->pagebuflen+=1024; + this->pages = (int*)realloc(this->pages, this->pagebuflen*sizeof(int)); + memset(&this->pages[oldlen], -1, (this->pagebuflen-oldlen)*sizeof(int)); + } + this->pages[pdfpage] = outputpage; if(pdfpage>this->pagepos) this->pagepos = pdfpage;