xpdf-3.02 fixes
[swftools.git] / lib / pdf / GFXOutputDev.cc
index 3814dbf..df8f27f 100644 (file)
@@ -106,7 +106,7 @@ struct mapping {
 {"Symbol",                "s050000l"},
 {"ZapfDingbats",          "d050000l"}};
 
-static int verbose = 1;
+static int verbose = 0;
 static int dbgindent = 0;
 static void dbg(char*format, ...)
 {
@@ -141,7 +141,7 @@ typedef struct _feature
 } feature_t;
 feature_t*featurewarnings = 0;
 
-static void warnfeature(char*feature,char fully)
+void GFXOutputDev::showfeature(char*feature,char fully, char warn)
 {
     feature_t*f = featurewarnings;
     while(f) {
@@ -153,7 +153,23 @@ static void warnfeature(char*feature,char fully)
     f->string = strdup(feature);
     f->next = featurewarnings;
     featurewarnings = f;
-    msg("<warning> %s not yet %ssupported!",feature,fully?"fully ":"");
+    if(warn) {
+       msg("<warning> %s not yet %ssupported!",feature,fully?"fully ":"");
+       if(this->config_break_on_warning) {
+           msg("<fatal> Aborting conversion due to unsupported feature");
+           exit(1);
+       }
+    } else {
+       msg("<notice> File contains %s",feature);
+    }
+}
+void GFXOutputDev::warnfeature(char*feature,char fully)
+{
+    showfeature(feature,fully,1);
+}
+void GFXOutputDev::infofeature(char*feature)
+{
+    showfeature(feature,0,0);
 }
 
 GFXOutputState::GFXOutputState() {
@@ -221,7 +237,6 @@ GFXOutputDev::GFXOutputDev(parameter_t*p)
 {
     this->jpeginfo = 0;
     this->textmodeinfo = 0;
-    this->ttfinfo = 0;
     this->linkinfo = 0;
     this->pbminfo = 0;
     this->type3active = 0;
@@ -244,18 +259,17 @@ GFXOutputDev::GFXOutputDev(parameter_t*p)
     this->pages = 0;
     this->pagebuflen = 0;
     this->pagepos = 0;
-  
-    this->forceType0Fonts=1;
     this->config_use_fontconfig=1;
+    this->config_break_on_warning=0;
 
     this->parameters = p;
 
     /* configure device */
     while(p) {
-       if(!strcmp(p->name,"forceType0Fonts")) {
-           this->forceType0Fonts = atoi(p->value);
-       } else if(!strcmp(p->name,"fontconfig")) {
+       if(!strcmp(p->name,"fontconfig")) {
            this->config_use_fontconfig = atoi(p->value);
+       } else if(!strcmp(p->name,"breakonwarning")) {
+           this->config_break_on_warning = atoi(p->value);
        }
        p = p->next;
     }
@@ -265,7 +279,7 @@ void GFXOutputDev::setDevice(gfxdevice_t*dev)
 {
     parameter_t*p = this->parameters;
 
-    /* TODO: get rid of this */
+    /* pass parameters to output device */
     this->device = dev;
     if(this->device) {
        while(p) {
@@ -615,9 +629,17 @@ gfxline_t* gfxPath_to_gfxline(GfxState*state, GfxPath*path, int closed, int user
     return result;
 }
 
-/*----------------------------------------------------------------------------
- * Primitive Graphic routines
- *----------------------------------------------------------------------------*/
+GBool GFXOutputDev::useTilingPatternFill()
+{
+    infofeature("tiled patterns");
+    return gFalse;
+}
+
+GBool GFXOutputDev::useShadedFills()
+{
+    infofeature("shaded fills");
+    return gFalse;
+}
 
 void GFXOutputDev::strokeGfxline(GfxState *state, gfxline_t*line)
 {
@@ -927,8 +949,6 @@ void GFXOutputDev::beginString(GfxState *state, GString *s)
 
     gfxmatrix_t m = this->current_font_matrix;
 
-    /*if(render != 3 && render != 0)
-       msg("<warning> Text rendering mode %d (%s) not fully supported yet (for text \"%s\")", render, renderModeDesc[render&7], makeStringPrintable(s->getCString()));*/
     states[statepos].textRender = render;
 }
 
@@ -1180,7 +1200,8 @@ void GFXOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl
     device->fill(device, clippath, &white);
 }
 
-void GFXOutputDev::processLink(Link *link, Catalog *catalog) 
+
+void GFXOutputDev::processLink(Link *link, Catalog *catalog)
 {
     double x1, y1, x2, y2, w;
     gfxline_t points[5];
@@ -1538,7 +1559,7 @@ char*GFXOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
       }
       FoFiType1C *cvt = FoFiType1C::make(fontBuf, fontLen);
       if(!cvt) return 0;
-      cvt->convertToType1(NULL, gTrue, FoFiWrite, f);
+      cvt->convertToType1(0, NULL, gTrue, FoFiWrite, f);
       //cvt->convertToCIDType0("test", f);
       //cvt->convertToType0("test", f);
       delete cvt;
@@ -1883,7 +1904,7 @@ void GFXOutputDev::updateFont(GfxState *state)
     if(embedded &&
        (gfxFont->getType() == fontType1 ||
        gfxFont->getType() == fontType1C ||
-       (gfxFont->getType() == fontCIDType0C && forceType0Fonts) ||
+        gfxFont->getType() == fontCIDType0C ||
        gfxFont->getType() == fontTrueType ||
        gfxFont->getType() == fontCIDType2
        ))
@@ -2039,10 +2060,6 @@ static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, int sizex,int sizey,
        /* TODO: pass image_dpi to device instead */
        dev->setparameter(dev, "next_bitmap_is_jpeg", "1");
 
-    gfxline_show(&p1,stdout);
-
-    printf("%.2f %.2f %.2f\n", m.m00, m.m10, m.tx);
-    printf("%.2f %.2f %.2f\n", m.m01, m.m11, m.ty);
     dev->fillbitmap(dev, &p1, &img, &m, 0);
 }
 
@@ -2380,7 +2397,8 @@ void GFXOutputDev::stroke(GfxState *state)
 
 void GFXOutputDev::fill(GfxState *state) 
 {
-    dbg("fill");
+    gfxcolor_t col = getFillColor(state);
+    dbg("fill %02x%02x%02x%02x",col.r,col.g,col.b,col.a);
 
     GfxPath * path = state->getPath();
     gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey);
@@ -2390,19 +2408,12 @@ void GFXOutputDev::fill(GfxState *state)
 
 void GFXOutputDev::eoFill(GfxState *state) 
 {
-    dbg("eofill");
-
-    GfxPath * path = state->getPath();
     gfxcolor_t col = getFillColor(state);
+    dbg("eofill %02x%02x%02x%02x",col.r,col.g,col.b,col.a);
 
+    GfxPath * path = state->getPath();
     gfxline_t*line= gfxPath_to_gfxline(state, path, 1, user_movex + clipmovex, user_movey + clipmovey);
-
-    if(getLogLevel() >= LOGLEVEL_TRACE)  {
-        msg("<trace> eofill\n");
-        dump_outline(line);
-    }
-
-    device->fill(device, line, &col);
+    fillGfxLine(state, line);
     gfxline_free(line);
 }
 
@@ -2625,7 +2636,6 @@ void GFXOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
     /*if(!forSoftMask) { ////???
        state->setFillOpacity(0.0);
     }*/
-    warnfeature("transparency groups",1);
     dbgindent+=2;
 }
 
@@ -2658,6 +2668,14 @@ void GFXOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
 
     dbg("paintTransparencyGroup blend=%s softmaskon=%d", blendmodes[state->getBlendMode()], states[statepos].softmask);
     msg("<verbose> paintTransparencyGroup blend=%s softmaskon=%d", blendmodes[state->getBlendMode()], states[statepos].softmask);
+   
+    if(state->getBlendMode() == gfxBlendNormal)
+       infofeature("transparency groups");
+    else {
+       char buffer[80];
+       sprintf(buffer, "%s blended transparency groups", blendmodes[state->getBlendMode()]);
+       warnfeature(buffer, 0);
+    }
 
     gfxresult_t*grouprecording = states[statepos].grouprecording;
    
@@ -2680,7 +2698,10 @@ void GFXOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Funct
            bbox[0], bbox[1], bbox[2], bbox[3], alpha, colToByte(rgb->c[0]), colToByte(rgb->c[1]), colToByte(rgb->c[2]));
     msg("<verbose> setSoftMask %.1f/%.1f/%.1f/%.1f alpha=%d backdrop=%02x%02x%02x",
            bbox[0], bbox[1], bbox[2], bbox[3], alpha, colToByte(rgb->c[0]), colToByte(rgb->c[1]), colToByte(rgb->c[2]));
-    warnfeature("soft masks",0);
+    if(!alpha)
+       infofeature("soft masks");
+    else
+       warnfeature("soft masks from alpha channel",0);
     
     states[statepos].olddevice = this->device;
     this->device = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t));
@@ -2691,6 +2712,10 @@ void GFXOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Funct
     states[statepos].softmask = 1;
 }
 
+static inline Guchar div255(int x) {
+  return (Guchar)((x + (x >> 8) + 0x80) >> 8);
+}
+
 void GFXOutputDev::clearSoftMask(GfxState *state)
 {
     if(!states[statepos].softmask)
@@ -2728,6 +2753,7 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
 
     gfxdevice_t belowrender;
     gfxdevice_render_init(&belowrender);
+    belowrender.setparameter(&belowrender, "fillwhite", "1"); //for isolated=0?
     belowrender.setparameter(&belowrender, "antialize", "2");
     belowrender.startpage(&belowrender, width, height);
     gfxresult_record_replay(below, &belowrender);
@@ -2753,14 +2779,12 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
        gfxcolor_t* l1 = &maskimg->data[maskimg->width*y];
        gfxcolor_t* l2 = &belowimg->data[belowimg->width*y];
        for(x=0;x<width;x++) {
-           l1->a = 255;
            l2->a = (77*l1->r + 151*l1->g + 28*l1->b) >> 8;
 
-           /* premultiply alpha... do we need this? (depends on output device)
-           l2->r = (l2->a*l2->r) >> 8;
-           l2->g = (l2->a*l2->g) >> 8;
-           l2->b = (l2->a*l2->b) >> 8;
-           */
+           /* premultiply alpha */
+           l2->r = div255(l2->a*l2->r);
+           l2->g = div255(l2->a*l2->g);
+           l2->b = div255(l2->a*l2->b);
 
            l1++;
            l2++;
@@ -2780,6 +2804,7 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
     belowresult->destroy(belowresult);
     states[statepos].softmaskrecording = 0;
 }
+  
 #endif
 
 /*class MemCheck