+
+ 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);
+ belowrender.setparameter(&belowrender, "fillwhite", "1"); //for isolated=0?
+ 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");
+
+ 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++) {
+ l2->a = (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);
+
+ l1++;
+ l2++;
+ }
+ }
+ gfxline_t*line = gfxline_makerectangle(0,0,width,height);
+
+ gfxmatrix_t matrix;
+ matrix.m00 = 1.0; matrix.m10 = 0.0; matrix.tx = 0.0;
+ matrix.m01 = 0.0; matrix.m11 = 1.0; matrix.ty = 0.0;
+
+ this->device->fillbitmap(this->device, line, belowimg, &matrix, 0);
+
+ mask->destroy(mask);
+ below->destroy(below);
+ maskresult->destroy(maskresult);
+ belowresult->destroy(belowresult);
+ states[statepos].softmaskrecording = 0;