synchronized with downstream git
[swftools.git] / lib / pdf / GFXOutputDev.cc
index 2c90c92..2596d25 100644 (file)
@@ -335,6 +335,19 @@ GFXGlobalParams::~GFXGlobalParams()
 #endif
 }
 #ifdef HAVE_FONTCONFIG
+static char stralphacmp(const char*s1, const char*s2)
+{
+    while(*s1 && *s2) {
+       /* skip over space, minus, comma etc. */
+       while(*s1>=32 && *s1<=63) s1++;
+       while(*s2>=32 && *s2<=63) s2++;
+       if(*s1!=*s2)
+           break;
+       s1++;s2++;
+    }
+    return *s1 - *s2;
+}
+
 static char fc_ismatch(FcPattern*match, char*family, char*style)
 {
     char*fcfamily=0,*fcstyle=0,*fcfullname=0,*filename=0;
@@ -348,7 +361,7 @@ static char fc_ismatch(FcPattern*match, char*family, char*style)
     if(scalable!=FcTrue || outline!=FcTrue)
        return 0;
 
-    if (!strcasecmp(fcfamily, family)) {
+    if (!stralphacmp(fcfamily, family)) {
        msg("<debug> Font %s-%s (%s) is a match for %s%s%s", fcfamily, fcstyle, filename, family, style?"-":"", style?style:"");
        return 1;
     } else {
@@ -419,6 +432,7 @@ char* fontconfig_searchForFont(char*name)
         fontfile_t*fd = global_fonts;
         while(fd) {
             FcConfigAppFontAddFile(config, (FcChar8*)fd->filename);
+            msg("<debug> Adding font %s to fontconfig", fd->filename);
             fd = fd->next;
         }
 
@@ -432,17 +446,21 @@ char* fontconfig_searchForFont(char*name)
 
        if(getLogLevel() >= LOGLEVEL_TRACE) {
            int t;
-           for(t=0;t<set->nfont;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("<trace> %s-%s -> %s", fcfamily, fcstyle, filename);
+           int p;
+           for(p=0;p<2;p++) {
+               for(t=0;t<set->nfont;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("<trace> %s (%s) -> %s", fcfamily, fcstyle, filename);
+                   }
                }
+               set =  FcConfigGetFonts(config, FcSetApplication);
            }
        }
     }
@@ -450,6 +468,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 +526,7 @@ static DisplayFontParamKind detectFontType(const char*filename)
 
 DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName)
 {
-    msg("<verbose> looking for font %s in global params", fontName->getCString());
+    msg("<verbose> looking for font %s", fontName->getCString());
 
     char*name = fontName->getCString();
     
@@ -565,8 +585,10 @@ DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName)
        }
        free(filename);
         return dfp;
+    } else {
+       msg("<verbose> Font %s not found\n", name);
+       return GlobalParams::getDisplayFont(fontName);
     }
-    return GlobalParams::getDisplayFont(fontName);
 }
 
 GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc)
@@ -589,6 +611,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;
@@ -602,6 +625,7 @@ GFXOutputDev::GFXOutputDev(InfoOutputDev*info, PDFDoc*doc)
     this->config_drawonlyshapes = 0;
     this->config_disable_polygon_conversion = 0;
     this->config_multiply = 1;
+    this->config_linkdatafile = 0;
     this->page2page = 0;
     this->num_pages = 0;
   
@@ -620,6 +644,8 @@ void GFXOutputDev::setParameter(const char*key, const char*value)
         this->config_drawonlyshapes = atoi(value);
     } else if(!strcmp(key,"extrafontdata")) {
         this->config_extrafontdata = atoi(value);
+    } else if(!strcmp(key,"linkdatafile")) {
+        this->config_linkdatafile = strdup(value);
     } else if(!strcmp(key,"convertgradients")) {
         this->config_convertgradients = atoi(value);
     } else if(!strcmp(key,"multiply")) {
@@ -1227,7 +1253,7 @@ void GFXOutputDev::fillGfxLine(GfxState *state, gfxline_t*line, char evenodd)
     gfxcolor_t col = getFillColor(state);
 
     if(getLogLevel() >= LOGLEVEL_TRACE)  {
-        msg("<trace> %sfill %02x%02x%02x%02x%s", evenodd?"eo":"", col.r, col.g, col.b, col.a);
+        msg("<trace> %sfill %02x%02x%02x%02x", evenodd?"eo":"", col.r, col.g, col.b, col.a);
         dump_outline(line);
     }
     device->fill(device, line, &col);
@@ -1416,10 +1442,13 @@ 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("<debug> 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) {
+    msg("<debug> 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_FILLSTROKE && state->getTransformedLineWidth()<1.0) ||
+       (render == RENDER_INVISIBLE)) {
+
        int space = this->current_fontinfo->space_char;
        if(config_extrafontdata && space>=0 && m.m00 && !m.m01) {
            /* space char detection */
@@ -1452,6 +1481,7 @@ void GFXOutputDev::drawChar(GfxState *state, double x, double y,
            msg("<notice> Some texts will be rendered as shape");
            gfxglobals->textmodeinfo = 1;
        }
+
        gfxline_t*glyph = current_gfxfont->glyphs[glyphid].line;
        gfxline_t*tglyph = gfxline_clone(glyph);
        gfxline_transform(tglyph, &m);
@@ -1535,10 +1565,11 @@ GBool GFXOutputDev::beginType3Char(GfxState *state, double x, double y, double d
 
        gfxmatrix_t m = this->current_font_matrix;
        this->transformXY(state, 0, 0, &m.tx, &m.ty);
-       m.m00*=INTERNAL_FONT_SIZE;
+
+       /*m.m00*=INTERNAL_FONT_SIZE;
        m.m01*=INTERNAL_FONT_SIZE;
        m.m10*=INTERNAL_FONT_SIZE;
-       m.m11*=INTERNAL_FONT_SIZE;
+       m.m11*=INTERNAL_FONT_SIZE;*/
 
        if(!current_fontinfo || (unsigned)charid >= current_fontinfo->num_glyphs || !current_fontinfo->glyphs[charid]) {
            msg("<error> Invalid charid %d for font", charid);
@@ -1820,8 +1851,13 @@ void GFXOutputDev::processLink(Link *link, Catalog *catalog)
     else if(s)
     {
         device->drawlink(device, points, s);
+       if(this->config_linkdatafile) {
+           FILE*fi = fopen(config_linkdatafile, "ab+");
+           fprintf(fi, "%s\n", s);
+           fclose(fi);
+       }
     }
-
+        
     msg("<verbose> \"%s\" link to \"%s\" (%d)", type, FIXNULL(s), page);
     free(s);s=0;
 }
@@ -1877,6 +1913,13 @@ void GFXOutputDev::restoreState(GfxState *state) {
   }
   if(states[statepos].state!=state) {
       msg("<fatal> 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;
@@ -2001,6 +2044,8 @@ void GFXOutputDev::updateFont(GfxState *state)
     current_gfxfont = this->current_fontinfo->getGfxFont();
     device->addfont(device, current_gfxfont);
     free(id);
+    
+    device->addfont(device, current_gfxfont);
 
     updateFontMatrix(state);
 }
@@ -2654,11 +2699,7 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state)
     
     this->device = states[statepos].olddevice;
     if(!this->device) {
-       msg("<fatal> Bad state nesting in transparency group");
-       msg("<fatal> Notice: this is a known problem, which will be fixed in 0.9.1");
-       msg("<fatal> In the meantime, please convert the file with -s poly2bitmap");
-       restoreState(state);
-       this->device = states[statepos].olddevice;
+       msg("<error> Invalid state nesting");
     }
     states[statepos].olddevice = 0;