X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FInfoOutputDev.cc;h=e6f3c032e7aee376e2ecf91aab99398ec23b9b91;hb=5f1e7e9ebbac00effaae0545c32fe9060215d125;hp=fd334525570988b0b6939b53df40c6f8647cad13;hpb=0784a8a882e7b98299fb6a90f0f9a7ebb322562b;p=swftools.git diff --git a/lib/pdf/InfoOutputDev.cc b/lib/pdf/InfoOutputDev.cc index fd33452..e6f3c03 100644 --- a/lib/pdf/InfoOutputDev.cc +++ b/lib/pdf/InfoOutputDev.cc @@ -1,9 +1,18 @@ +#include "config.h" #include "Object.h" -#include "SplashTypes.h" +#include "InfoOutputDev.h" #include "SplashOutputDev.h" +#ifdef HAVE_POPPLER +#include +#include +#include +#include +#else +#include "SplashTypes.h" #include "SplashPath.h" +#include "SplashFont.h" #include "SplashFontFile.h" -#include "InfoOutputDev.h" +#endif #include "GfxState.h" #include "../log.h" #include @@ -11,8 +20,11 @@ InfoOutputDev::InfoOutputDev(XRef*xref) { num_links = 0; - num_images = 0; + num_jpeg_images = 0; + num_ppm_images = 0; num_fonts = 0; + num_polygons= 0; + fonts = 0; currentfont = 0; currentglyph = 0; id2font = new GHash(1); @@ -31,8 +43,8 @@ InfoOutputDev::~InfoOutputDev() } id2font->killIter(&i); - delete id2font; - delete splash; + delete id2font;id2font=0; + delete splash;splash=0; } void FontInfo::grow(int size) { @@ -49,6 +61,10 @@ FontInfo::FontInfo() this->num_glyphs = 0; this->glyphs = 0; this->splash_font = 0; + this->lastchar = -1; + this->lastx = 0; + this->lasty = 0; + this->gfxfont = 0; } FontInfo::~FontInfo() { @@ -65,6 +81,7 @@ FontInfo::~FontInfo() glyphs[t]=0; } } + free(glyphs);glyphs=0; } GBool InfoOutputDev::upsideDown() {return gTrue;} GBool InfoOutputDev::useDrawChar() {return gTrue;} @@ -91,6 +108,108 @@ void InfoOutputDev::drawLink(Link *link, Catalog *catalog) { num_links++; } + +/* there's not yet a way to set this */ +int config_fontquality = 10; +int config_bigchar = 0; + +/* } else if(!strcmp(key,"fontquality")) { + this->config_fontquality = atof(value); + if(this->config_fontquality<=1) + this->config_fontquality=1; + } else if(!strcmp(key,"bigchar")) { + this->config_bigchar = atoi(value); + } + */ + +gfxfont_t* InfoOutputDev::createGfxFont(GfxFont*xpdffont, FontInfo*src) +{ + gfxfont_t*font = (gfxfont_t*)malloc(sizeof(gfxfont_t)); + memset(font, 0, sizeof(gfxfont_t)); + + font->glyphs = (gfxglyph_t*)malloc(sizeof(gfxglyph_t)*src->num_glyphs); + 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; + int len = path?path->getLength():0; + //printf("glyph %d) %08x (%d line segments)\n", t, path, len); + gfxglyph_t*glyph = &font->glyphs[font->num_glyphs]; + src->glyphs[t]->glyphid = font->num_glyphs; + glyph->unicode = src->glyphs[t]->unicode; + if(glyph->unicode >= font->max_unicode) + font->max_unicode = glyph->unicode+1; + gfxdrawer_t drawer; + gfxdrawer_target_gfxline(&drawer); + int s; + int count = 0; + double xmax = 0; + for(s=0;sgetPoint(s, &x, &y, &f); + if(!s || x > xmax) + xmax = x; + if(f&splashPathFirst) { + drawer.moveTo(&drawer, x*scale, y*scale); + } + if(f&splashPathCurve) { + double x2,y2; + path->getPoint(++s, &x2, &y2, &f); + if(f&splashPathCurve) { + double x3,y3; + path->getPoint(++s, &x3, &y3, &f); + gfxdraw_cubicTo(&drawer, x*scale, y*scale, x2*scale, y2*scale, x3*scale, y3*scale, quality); + } else { + drawer.splineTo(&drawer, x*scale, y*scale, x2*scale, y2*scale); + } + } else { + drawer.lineTo(&drawer, x*scale, y*scale); + } + // printf("%f %f %s %s\n", x, y, (f&splashPathCurve)?"curve":"", + // (f&splashPathFirst)?"first":"", + // (f&splashPathLast)?"last":""); + } + + glyph->line = (gfxline_t*)drawer.result(&drawer); + 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(config_bigchar) { + double max = src->glyphs[t]->advance_max; + if(max>0 && max > glyph->advance) { + glyph->advance = max; + } + } + + font->num_glyphs++; + } + } + font->unicode2glyph = (int*)malloc(sizeof(int)*font->max_unicode); + memset(font->unicode2glyph, -1, sizeof(int)*font->max_unicode); + for(t=0;tnum_glyphs;t++) { + if(font->glyphs[t].unicode>0 && font->glyphs[t].unicodemax_unicode) { + font->unicode2glyph[font->glyphs[t].unicode] = t; + } + + } + msg(" %d glyphs.", t, font->num_glyphs); + return font; +} + double InfoOutputDev::getMaximumFontSize(char*id) { FontInfo*info = (FontInfo*)id2font->lookup(id); @@ -151,8 +270,30 @@ void InfoOutputDev::updateFont(GfxState *state) state->setFont(font, 1024.0); splash->doUpdateFont(state); currentfont->splash_font = splash->getCurrentFont(); + if(currentfont->splash_font) { + currentfont->ascender = currentfont->splash_font->ascender; + currentfont->descender = currentfont->splash_font->descender; + } else { + currentfont->ascender = currentfont->descender = 0; + } + + currentfont->gfxfont = this->createGfxFont(font, currentfont); + currentfont->gfxfont->id = strdup(id); + fonts = gfxfontlist_addfont(fonts, currentfont->gfxfont); + free(id); } + +void InfoOutputDev::fill(GfxState *state) +{ + num_polygons++; +} + +void InfoOutputDev::eoFill(GfxState *state) +{ + num_polygons++; +} + FontInfo* InfoOutputDev::getFont(char*id) { return (FontInfo*)id2font->lookup(id); @@ -180,13 +321,25 @@ void InfoOutputDev::drawChar(GfxState *state, double x, double y, GlyphInfo*g = currentfont->glyphs[code]; if(!g) { g = currentfont->glyphs[code] = new GlyphInfo(); + g->advance_max = 0; + currentfont->splash_font->last_advance = -1; g->path = currentfont->splash_font->getGlyphPath(code); + g->advance = currentfont->splash_font->last_advance; g->unicode = 0; } if(uLen && (u[0]>=32 && u[0]unicode || !g->unicode)) { g->unicode = u[0]; } + if(currentfont->lastchar>=0 && currentfont->lasty == y) { + double xshift = x - currentfont->lastx; + if(xshift>=0 && xshift > g->advance_max) { + g->advance_max = xshift; + } + } + currentfont->lastx = x; + currentfont->lasty = y; + currentfont->lastchar = code; } GBool InfoOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen) @@ -257,14 +410,16 @@ void InfoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) { - num_images++; + if(str->getKind()==strDCT) num_jpeg_images++; else num_ppm_images++; + OutputDev::drawImageMask(state,ref,str,width,height,invert,inlineImg); } void InfoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, int *maskColors, GBool inlineImg) { - num_images++; + if(str->getKind()==strDCT) num_jpeg_images++; else num_ppm_images++; + OutputDev::drawImage(state,ref,str,width,height,colorMap,maskColors,inlineImg); } void InfoOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, @@ -274,6 +429,8 @@ void InfoOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int maskWidth, int maskHeight, GBool maskInvert) { + if(str->getKind()==strDCT) num_jpeg_images++; else num_ppm_images++; + OutputDev::drawMaskedImage(state,ref,str,width,height,colorMap,maskStr,maskWidth,maskHeight,maskInvert); } @@ -284,5 +441,7 @@ void InfoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *st int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap) { + if(str->getKind()==strDCT) num_jpeg_images++; else num_ppm_images++; + OutputDev::drawSoftMaskedImage(state,ref,str,width,height,colorMap,maskStr,maskWidth,maskHeight,maskColorMap); }