X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpdf%2FGFXOutputDev.cc;h=441a92b003e72bd1f4c2779baba3af01c311b43c;hb=711659af8759d3939ef395e04f81191a43049a19;hp=e5f21f3ffc39df4ca300b7425d0f93e5ef138fb9;hpb=0c8078b9fa9e2273e4dee6356beccbc35a592a26;p=swftools.git diff --git a/lib/pdf/GFXOutputDev.cc b/lib/pdf/GFXOutputDev.cc index e5f21f3..441a92b 100644 --- a/lib/pdf/GFXOutputDev.cc +++ b/lib/pdf/GFXOutputDev.cc @@ -419,6 +419,7 @@ char* fontconfig_searchForFont(char*name) fontfile_t*fd = global_fonts; while(fd) { FcConfigAppFontAddFile(config, (FcChar8*)fd->filename); + msg(" Adding font %s to fontconfig", fd->filename); fd = fd->next; } @@ -432,17 +433,21 @@ char* fontconfig_searchForFont(char*name) if(getLogLevel() >= LOGLEVEL_TRACE) { int t; - for(t=0;tnfont;t++) { - char*fcfamily=0,*fcstyle=0,*filename=0; - FcBool scalable=FcFalse, outline=FcFalse; - FcPatternGetString(set->fonts[t], "family", 0, (FcChar8**)&fcfamily); - FcPatternGetString(set->fonts[t], "style", 0, (FcChar8**)&fcstyle); - FcPatternGetString(set->fonts[t], "file", 0, (FcChar8**)&filename); - FcPatternGetBool(set->fonts[t], "outline", 0, &outline); - FcPatternGetBool(set->fonts[t], "scalable", 0, &scalable); - if(scalable && outline) { - msg(" %s-%s -> %s", fcfamily, fcstyle, filename); + int p; + for(p=0;p<2;p++) { + for(t=0;tnfont;t++) { + char*fcfamily=0,*fcstyle=0,*filename=0; + FcBool scalable=FcFalse, outline=FcFalse; + FcPatternGetString(set->fonts[t], "family", 0, (FcChar8**)&fcfamily); + FcPatternGetString(set->fonts[t], "style", 0, (FcChar8**)&fcstyle); + FcPatternGetString(set->fonts[t], "file", 0, (FcChar8**)&filename); + FcPatternGetBool(set->fonts[t], "outline", 0, &outline); + FcPatternGetBool(set->fonts[t], "scalable", 0, &scalable); + if(scalable && outline) { + msg(" %s (%s) -> %s", fcfamily, fcstyle, filename); + } } + set = FcConfigGetFonts(config, FcSetApplication); } } } @@ -450,6 +455,8 @@ char* fontconfig_searchForFont(char*name) char*family = strdup(name); char*style = 0; char*dash = strchr(family, '-'); + if(!dash) dash = strchr(family, ','); + FcPattern*pattern = 0; if(dash) { *dash = 0; @@ -506,7 +513,7 @@ static DisplayFontParamKind detectFontType(const char*filename) DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName) { - msg(" looking for font %s in global params", fontName->getCString()); + msg(" looking for font %s", fontName->getCString()); char*name = fontName->getCString(); @@ -565,8 +572,10 @@ DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName) } free(filename); return dfp; + } else { + msg(" Font %s not found\n", name); + return GlobalParams::getDisplayFont(fontName); } - return GlobalParams::getDisplayFont(fontName); } GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) @@ -589,6 +598,7 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) this->user_clipy1 = 0; this->user_clipx2 = 0; this->user_clipy2 = 0; + this->current_gfxfont = 0; this->current_fontinfo = 0; this->current_text_stroke = 0; this->current_text_clip = 0; @@ -599,7 +609,8 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc) this->config_remapunicode=0; this->config_transparent=0; this->config_extrafontdata = 0; - this->config_optimize_polygons = 1; + this->config_drawonlyshapes = 0; + this->config_disable_polygon_conversion = 0; this->config_multiply = 1; this->page2page = 0; this->num_pages = 0; @@ -615,6 +626,8 @@ void GFXOutputDev::setParameter(const char*key, const char*value) this->config_remapunicode = atoi(value); } else if(!strcmp(key,"transparent")) { this->config_transparent = atoi(value); + } else if(!strcmp(key,"drawonlyshapes")) { + this->config_drawonlyshapes = atoi(value); } else if(!strcmp(key,"extrafontdata")) { this->config_extrafontdata = atoi(value); } else if(!strcmp(key,"convertgradients")) { @@ -623,8 +636,8 @@ void GFXOutputDev::setParameter(const char*key, const char*value) 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,"disable_polygon_conversion")) { + this->config_disable_polygon_conversion = atoi(value); } } @@ -1219,20 +1232,21 @@ gfxcolor_t getFillColor(GfxState * state) return col; } -void GFXOutputDev::fillGfxLine(GfxState *state, gfxline_t*line) +void GFXOutputDev::fillGfxLine(GfxState *state, gfxline_t*line, char evenodd) { gfxcolor_t col = getFillColor(state); if(getLogLevel() >= LOGLEVEL_TRACE) { - msg(" fill %02x%02x%02x%02x", col.r, col.g, col.b, col.a); + msg(" %sfill %02x%02x%02x%02x", evenodd?"eo":"", col.r, col.g, col.b, col.a); dump_outline(line); } device->fill(device, line, &col); } -void GFXOutputDev::clipToGfxLine(GfxState *state, gfxline_t*line) +void GFXOutputDev::clipToGfxLine(GfxState *state, gfxline_t*line, char evenodd) { if(getLogLevel() >= LOGLEVEL_TRACE) { + msg(" %sclip", evenodd?"eo":""); dump_outline(line); } gfxbbox_t bbox = gfxline_getbbox(line); @@ -1247,12 +1261,12 @@ void GFXOutputDev::clip(GfxState *state) GfxPath * path = state->getPath(); msg(" clip"); gfxline_t*line = gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey); - if(config_optimize_polygons) { + if(!config_disable_polygon_conversion) { gfxline_t*line2 = gfxpoly_circular_to_evenodd(line, DEFAULT_GRID); gfxline_free(line); line = line2; } - clipToGfxLine(state, line); + clipToGfxLine(state, line, 0); gfxline_free(line); } @@ -1260,7 +1274,7 @@ void GFXOutputDev::eoClip(GfxState *state) { GfxPath * path = state->getPath(); gfxline_t*line = gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey); - clipToGfxLine(state, line); + clipToGfxLine(state, line, 1); gfxline_free(line); } void GFXOutputDev::clipToStrokePath(GfxState *state) @@ -1412,10 +1426,35 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y, gfxmatrix_t m = this->current_font_matrix; this->transformXY(state, x-originX, y-originY, &m.tx, &m.ty); //m.tx += originX; m.ty += originY; - - msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d render=%d glyphid=%d font=%08x",m.tx,m.ty,(charid&127)>=32?charid:'?', charid, u, uLen, font->isCIDFont(), render, glyphid, current_gfxfont); - if(render == RENDER_FILL || render == RENDER_INVISIBLE) { + msg(" drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d render=%d glyphid=%d font=%08x",m.tx,m.ty,(charid&127)>=32?charid:'?', charid, u, uLen, font->isCIDFont(), render, glyphid, current_gfxfont); + + if((render == RENDER_FILL && !config_drawonlyshapes) || render == RENDER_INVISIBLE) { + int space = this->current_fontinfo->space_char; + if(config_extrafontdata && space>=0 && m.m00 && !m.m01) { + /* space char detection */ + if(last_char_gfxfont == current_gfxfont && + last_char_y == m.ty && + !last_char_was_space) { + double expected_x = last_char_x + current_gfxfont->glyphs[last_char].advance*m.m00; + int space = this->current_fontinfo->space_char; + if(m.tx - expected_x >= m.m00*64) { + msg(" There's a %f (%f) pixel gap between char %d and char %d, I'm inserting a space here", + m.tx-expected_x, + (m.tx-expected_x)/m.m00, + last_char, glyphid); + gfxmatrix_t m2 = m; + m2.tx = expected_x + (m.tx - expected_x - current_gfxfont->glyphs[space].advance*m.m00)/2; + if(m2.tx < expected_x) m2.tx = expected_x; + device->drawchar(device, current_gfxfont, space, &col, &m2); + } + } + last_char_gfxfont = current_gfxfont; + last_char = glyphid; + last_char_x = m.tx; + last_char_y = m.ty; + last_char_was_space = GLYPH_IS_SPACE(¤t_gfxfont->glyphs[glyphid]); + } device->drawchar(device, current_gfxfont, glyphid, &col, &m); } else { msg(" Drawing glyph %d as shape", charid); @@ -1453,11 +1492,11 @@ void GFXOutputDev::endString(GfxState *state) however */ device->setparameter(device, "mark","TXT"); if((render&3) == RENDER_FILL) { - fillGfxLine(state, current_text_stroke); + fillGfxLine(state, current_text_stroke, 0); gfxline_free(current_text_stroke); current_text_stroke = 0; } else if((render&3) == RENDER_FILLSTROKE) { - fillGfxLine(state, current_text_stroke); + fillGfxLine(state, current_text_stroke, 0); strokeGfxline(state, current_text_stroke,0); gfxline_free(current_text_stroke); current_text_stroke = 0; @@ -1477,7 +1516,7 @@ void GFXOutputDev::endTextObject(GfxState *state) if(current_text_clip) { device->setparameter(device, "mark","TXT"); - clipToGfxLine(state, current_text_clip); + clipToGfxLine(state, current_text_clip, 0); device->setparameter(device, "mark",""); gfxline_free(current_text_clip); current_text_clip = 0; @@ -1601,6 +1640,8 @@ void GFXOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl states[statepos].dashPattern = 0; states[statepos].dashLength = 0; states[statepos].dashStart = 0; + + this->last_char_gfxfont = 0; } @@ -1846,6 +1887,13 @@ void GFXOutputDev::restoreState(GfxState *state) { } if(states[statepos].state!=state) { msg(" bad state nesting"); + if(verbose) { + int t; + for(t=0;t<=statepos;t++) { + printf("%08x ", states[t].state); + } + printf("\n"); + } exit(1); } states[statepos].state=0; @@ -2468,12 +2516,12 @@ void GFXOutputDev::fill(GfxState *state) GfxPath * path = state->getPath(); gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey); - if(config_optimize_polygons) { + if(!config_disable_polygon_conversion) { gfxline_t*line2 = gfxpoly_circular_to_evenodd(line, DEFAULT_GRID); gfxline_free(line); line = line2; } - fillGfxLine(state, line); + fillGfxLine(state, line, 0); gfxline_free(line); } @@ -2484,7 +2532,7 @@ void GFXOutputDev::eoFill(GfxState *state) GfxPath * path = state->getPath(); gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey); - fillGfxLine(state, line); + fillGfxLine(state, line, 1); gfxline_free(line); } @@ -2504,8 +2552,8 @@ void addGlobalFont(const char*filename) memset(f, 0, sizeof(fontfile_t)); f->filename = filename; int len = strlen(filename); - char*r1 = strrchr(filename, '/'); - char*r2 = strrchr(filename, '\\'); + char*r1 = strrchr((char*)filename, '/'); + char*r2 = strrchr((char*)filename, '\\'); if(r2>r1) r1 = r2; if(r1) { @@ -2623,11 +2671,7 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state) this->device = states[statepos].olddevice; if(!this->device) { - msg(" Bad state nesting in transparency group"); - msg(" Notice: this is a known problem, which will be fixed in 0.9.1"); - msg(" In the meantime, please convert the file with -s poly2bitmap"); - restoreState(state); - this->device = states[statepos].olddevice; + msg(" Invalid state nesting"); } states[statepos].olddevice = 0;