+
+ if(!states[statepos].softmaskrecording || strcmp(this->device->name, "record")) {
+ msg("<error> Error in softmask/tgroup ordering");
+ return;
+ }
+
+ gfxresult_t*mask = states[statepos].softmaskrecording;
+ gfxresult_t*below = this->device->finish(this->device);
+ this->device = states[statepos].olddevice;
+
+ /* get outline of all objects below the soft mask */
+ gfxdevice_t uniondev;
+ gfxdevice_union_init(&uniondev, 0);
+ gfxresult_record_replay(below, &uniondev);
+ gfxline_t*belowoutline = gfxdevice_union_getunion(&uniondev);
+ uniondev.finish(&uniondev);
+
+ gfxbbox_t bbox = gfxline_getbbox(belowoutline);
+#if 0
+ this->device->startclip(this->device, belowoutline);
+ gfxresult_record_replay(below, this->device);
+ gfxresult_record_replay(mask, this->device);
+ this->device->endclip(this->device);
+ gfxline_free(belowoutline);
+#endif
+
+ int width = (int)bbox.xmax,height = (int)bbox.ymax;
+
+ 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);
+ maskrender.startpage(&maskrender, width, height);
+ gfxresult_record_replay(mask, &maskrender);
+ maskrender.endpage(&maskrender);
+ gfxresult_t* maskresult = maskrender.finish(&maskrender);
+ gfximage_t* maskimg = (gfximage_t*)maskresult->get(maskresult,"page0");
+
+ if(belowimg->width != maskimg->width || belowimg->height != maskimg->height) {
+ msg("<fatal> Internal error in mask drawing");
+ return;
+ }
+
+ int y,x;
+ for(y=0;y<height;y++) {
+ gfxcolor_t* l1 = &maskimg->data[maskimg->width*y];
+ gfxcolor_t* l2 = &belowimg->data[belowimg->width*y];
+ for(x=0;x<width;x++) {
+ 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->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++;
+ }
+ }
+ gfxline_t*line = gfxline_makerectangle(0,0,width,height);