fixed a soft mask bug
[swftools.git] / lib / pdf / GFXOutputDev.cc
index 81cb642..1e5036a 100644 (file)
@@ -106,7 +106,7 @@ struct mapping {
 {"Symbol",                "s050000l"},
 {"ZapfDingbats",          "d050000l"}};
 
-static int verbose = 0;
+static int verbose = 1;
 static int dbgindent = 0;
 static void dbg(char*format, ...)
 {
@@ -179,6 +179,7 @@ GFXOutputState::GFXOutputState() {
     this->transparencygroup = 0;
     this->softmask = 0;
     this->grouprecording = 0;
+    this->isolated = 0;
 }
 
 GBool GFXOutputDev::interpretType3Chars() 
@@ -263,6 +264,8 @@ GFXOutputDev::GFXOutputDev(parameter_t*p)
     this->config_break_on_warning=0;
 
     this->parameters = p;
+  
+    memset(states, 0, sizeof(states));
 
     /* configure device */
     while(p) {
@@ -1200,7 +1203,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];
@@ -1558,7 +1562,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;
@@ -2396,7 +2400,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);
@@ -2406,19 +2411,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);
 }
 
@@ -2615,7 +2613,6 @@ BBox mkBBox(GfxState*state, double*bbox, double width, double height)
     return nbbox;
 }
 
-#if xpdfUpdateVersion >= 16
 void GFXOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
                                      GfxColorSpace *blendingColorSpace,
                                      GBool isolated, GBool knockout,
@@ -2630,10 +2627,12 @@ void GFXOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
     dbg("beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask);
     dbg("using clipping rect %f/%f/%f/%f\n", rect.posx,rect.posy,rect.width,rect.height);
     msg("<verbose> beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask);
+    
     states[statepos].createsoftmask |= forSoftMask;
     states[statepos].transparencygroup = !forSoftMask;
-    states[statepos].olddevice = this->device;
+    states[statepos].isolated = isolated;
 
+    states[statepos].olddevice = this->device;
     this->device = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t));
 
     gfxdevice_record_init(this->device);
@@ -2715,6 +2714,7 @@ void GFXOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Funct
     dbg("softmaskrecording is %08x at statepos %d\n", states[statepos].softmaskrecording, statepos);
     
     states[statepos].softmask = 1;
+    states[statepos].softmask_alpha = alpha;
 }
 
 static inline Guchar div255(int x) {
@@ -2758,12 +2758,16 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
 
     gfxdevice_t belowrender;
     gfxdevice_render_init(&belowrender);
+    if(states[statepos+1].isolated) {
+       belowrender.setparameter(&belowrender, "fillwhite", "1");
+    }
     belowrender.setparameter(&belowrender, "antialize", "2");
     belowrender.startpage(&belowrender, width, height);
     gfxresult_record_replay(below, &belowrender);
     belowrender.endpage(&belowrender);
     gfxresult_t* belowresult = belowrender.finish(&belowrender);
     gfximage_t* belowimg = (gfximage_t*)belowresult->get(belowresult,"page0");
+    writePNG("below.png", (unsigned char*)belowimg->data, belowimg->width, belowimg->height);
 
     gfxdevice_t maskrender;
     gfxdevice_render_init(&maskrender);
@@ -2783,12 +2787,18 @@ 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++) {
-           l2->a = (77*l1->r + 151*l1->g + 28*l1->b) >> 8;
+           int alpha;
+           if(states[statepos].softmask_alpha) {
+               alpha = l1->a;
+           } else {
+               alpha = (77*l1->r + 151*l1->g + 28*l1->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);
+           l2->a = div255(alpha*l2->a);
+           l2->r = div255(alpha*l2->r);
+           l2->g = div255(alpha*l2->g);
+           l2->b = div255(alpha*l2->b);
 
            l1++;
            l2++;
@@ -2809,8 +2819,6 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
     states[statepos].softmaskrecording = 0;
 }
   
-#endif
-
 /*class MemCheck
 {
     public: ~MemCheck()