added new output devices
[swftools.git] / lib / pdf / BitmapOutputDev.cc
1 /* InfoOutputDev.h
2
3    Output Device which creates a bitmap.
4
5    Swftools is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    Swftools is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with swftools; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <memory.h>
22 #include "BitmapOutputDev.h"
23 #include "GFXOutputDev.h"
24 #include "SplashBitmap.h"
25 #include "../log.h"
26
27 static SplashColor splash_white = {255,255,255};
28 static SplashColor splash_black = {255,255,255};
29
30 BitmapOutputDev::BitmapOutputDev(InfoOutputDev*info, PDFDoc*doc)
31 {
32     this->info = info;
33     this->doc = doc;
34     this->xref = doc->getXRef();
35     this->rgbdev = new SplashOutputDev(splashModeRGB8, 1, gFalse, splash_white, gTrue, gTrue);
36     this->alphadev = new SplashOutputDev(splashModeMono1, 1, gFalse, splash_black, gTrue, gTrue);
37     this->gfxdev = new GFXOutputDev(info, this->doc);
38     this->rgbdev->startDoc(this->xref);
39     this->alphadev->startDoc(this->xref);
40     memset(rgbdev->getBitmap()->getAlphaPtr(), 0, rgbdev->getBitmap()->getWidth()*rgbdev->getBitmap()->getHeight());
41
42     this->config_bitmapfonts = 0;
43 }
44 BitmapOutputDev::~BitmapOutputDev()
45 {
46 }
47
48 void BitmapOutputDev::setDevice(gfxdevice_t*dev)
49 {
50     this->dev = dev;
51     this->gfxdev->setDevice(dev);
52 }
53 void BitmapOutputDev::setMove(int x,int y)
54 {
55 }
56 void BitmapOutputDev::setClip(int x1,int y1,int x2,int y2)
57 {
58 }
59 void BitmapOutputDev::setParameter(const char*key, const char*value)
60 {
61 }
62 void BitmapOutputDev::preparePage(int pdfpage, int outputpage)
63 {
64 }
65
66 void getBitmapBBox(Guchar*alpha, int width, int height, int*xmin, int*ymin, int*xmax, int*ymax)
67 {
68     *ymin = -1;
69     *xmin = width;
70     *xmax = 0;
71     int x,y;
72     for(y=0;y<height;y++) {
73         Guchar*a = &alpha[y*width];
74         for(x=0;x<width;x++) {
75             if(a[x]) break;
76         }
77         int left = x; //first occupied pixel from left
78         int right = x+1; //last non-occupied pixel from right
79         for(;x<width;x++) {
80             if(a[x]) right=x+1;
81         }
82
83         if(left!=width) {
84             if(*ymin<0) 
85                 *ymin=y;
86             *ymax=y+1;
87             if(left<*xmin) *xmin = left;
88             if(right>*xmax) *xmax = right;
89         }
90     }
91     if(*xmin>=*xmax || *ymin>=*ymax) {
92         *xmin = 0;
93         *ymin = 0;
94         *xmax = 0;
95         *ymax = 0;
96     }
97 }
98
99 void BitmapOutputDev::flush()
100 {
101     int width = rgbdev->getBitmapWidth();
102     int height = rgbdev->getBitmapHeight();
103     SplashColorPtr rgb = rgbdev->getBitmap()->getDataPtr();
104     Guchar*alpha = rgbdev->getBitmap()->getAlphaPtr();
105
106     int xmin,ymin,xmax,ymax;
107     getBitmapBBox(alpha, width, height, &xmin,&ymin,&xmax,&ymax);
108
109     msg("<verbose> Flushing graphics (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax);
110     
111     if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do
112         return;
113
114     if(sizeof(SplashColor)!=3) {
115         msg("<error> sizeof(SplashColor)!=3");
116         return;
117     }
118     //xmin = ymin = 0;
119     //xmax = width;
120     //ymax = height;
121
122     int rangex = xmax-xmin;
123     int rangey = ymax-ymin;
124     gfximage_t*img = (gfximage_t*)malloc(sizeof(gfximage_t)); 
125     img->data = (gfxcolor_t*)malloc(rangex * rangey * 4);
126     img->width = rangex;
127     img->height = rangey;
128     int x,y;
129     for(y=0;y<rangey;y++) {
130         SplashColorPtr in=&rgb[((y+ymin)*width+xmin)*sizeof(SplashColor)];
131         gfxcolor_t*out = &img->data[y*rangex];
132         Guchar*ain = &alpha[(y+ymin)*width+xmax];
133         for(x=0;x<rangex;x++) {
134             out[x].r = in[x*3+0];
135             out[x].g = in[x*3+1];
136             out[x].b = in[x*3+2];
137             out[x].a = ain[x];
138         }
139     }
140
141     gfxmatrix_t m;
142     m.tx = xmin;
143     m.ty = ymin;
144     m.m00 = m.m11 = 1;
145     m.m10 = m.m01 = 0;
146
147     gfxline_t* line = gfxline_makerectangle(xmin, ymin, xmax, ymax);
148     dev->fillbitmap(dev, line, img, &m, 0);
149     gfxline_free(line);
150
151     memset(rgbdev->getBitmap()->getAlphaPtr(), 0, rgbdev->getBitmap()->getWidth()*rgbdev->getBitmap()->getHeight());
152     memset(rgbdev->getBitmap()->getDataPtr(), 0, rgbdev->getBitmap()->getWidth()*rgbdev->getBitmap()->getHeight()*sizeof(SplashColor));
153
154     free(img->data);img->data=0;free(img);img=0;
155 }
156
157 void BitmapOutputDev::startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2)
158 {
159     msg("<verbose> startPage");
160     this->width = (int)x2 - (int)x1; //not used yet
161     this->height = (int)y2 - (int)y1;
162     rgbdev->startPage(pageNum, state, x1, y1, x2, y2);
163     alphadev->startPage(pageNum, state, x1, y1, x2, y2);
164 }
165
166 void BitmapOutputDev::endPage()
167 {
168     msg("<verbose> endPage");
169     this->flush();
170
171     /* splash will now destroy alpha, and paint the 
172        background color into the "holes" in the bitmap */
173     rgbdev->endPage();
174     alphadev->endPage();
175 }
176
177 GBool BitmapOutputDev::upsideDown()
178 {
179     rgbdev->upsideDown();
180     return alphadev->upsideDown();
181 }
182
183 GBool BitmapOutputDev::useDrawChar()
184 {
185     rgbdev->useDrawChar();
186     return alphadev->useDrawChar();
187 }
188
189 GBool BitmapOutputDev::useTilingPatternFill()
190 {
191     rgbdev->useTilingPatternFill();
192     return alphadev->useTilingPatternFill();
193 }
194
195 GBool BitmapOutputDev::useShadedFills()
196 {
197     rgbdev->useTilingPatternFill();
198     return alphadev->useTilingPatternFill();
199 }
200
201 GBool BitmapOutputDev::useDrawForm()
202 {
203     rgbdev->useDrawForm();
204     return alphadev->useDrawForm();
205 }
206
207 GBool BitmapOutputDev::interpretType3Chars()
208 {
209     if(config_bitmapfonts) {
210         rgbdev->interpretType3Chars();
211         return alphadev->interpretType3Chars();
212     } else {
213         return gfxdev->interpretType3Chars();
214     }
215 }
216
217 GBool BitmapOutputDev::needNonText() 
218 {
219     rgbdev->needNonText();
220     return alphadev->needNonText();
221 }
222 /*GBool BitmapOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
223                            int rotate, GBool useMediaBox, GBool crop,
224                            int sliceX, int sliceY, int sliceW, int sliceH,
225                            GBool printing, Catalog *catalog,
226                            GBool (*abortCheckCbk)(void *data),
227                            void *abortCheckCbkData)
228 {
229     return gTrue;
230 }*/
231 void BitmapOutputDev::setDefaultCTM(double *ctm) 
232 {
233     rgbdev->setDefaultCTM(ctm);
234     alphadev->setDefaultCTM(ctm);
235 }
236 void BitmapOutputDev::saveState(GfxState *state) 
237 {
238     rgbdev->saveState(state);
239     alphadev->saveState(state);
240 }
241 void BitmapOutputDev::restoreState(GfxState *state) 
242 {
243     rgbdev->restoreState(state);
244     alphadev->restoreState(state);
245 }
246 void BitmapOutputDev::updateAll(GfxState *state)
247 {
248     rgbdev->updateAll(state);
249     alphadev->updateAll(state);
250 }
251 void BitmapOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32)
252 {
253     rgbdev->updateCTM(state,m11,m12,m21,m22,m31,m32);
254     alphadev->updateCTM(state,m11,m12,m21,m22,m31,m32);
255 }
256 void BitmapOutputDev::updateLineDash(GfxState *state)
257 {
258     rgbdev->updateLineDash(state);
259     alphadev->updateLineDash(state);
260 }
261 void BitmapOutputDev::updateFlatness(GfxState *state)
262 {
263     rgbdev->updateFlatness(state);
264     alphadev->updateFlatness(state);
265 }
266 void BitmapOutputDev::updateLineJoin(GfxState *state)
267 {
268     rgbdev->updateLineJoin(state);
269     alphadev->updateLineJoin(state);
270 }
271 void BitmapOutputDev::updateLineCap(GfxState *state)
272 {
273     rgbdev->updateLineCap(state);
274     alphadev->updateLineCap(state);
275 }
276 void BitmapOutputDev::updateMiterLimit(GfxState *state)
277 {
278     rgbdev->updateMiterLimit(state);
279     alphadev->updateMiterLimit(state);
280 }
281 void BitmapOutputDev::updateLineWidth(GfxState *state)
282 {
283     rgbdev->updateLineWidth(state);
284     alphadev->updateLineWidth(state);
285 }
286 void BitmapOutputDev::updateStrokeAdjust(GfxState *state)
287 {
288     rgbdev->updateStrokeAdjust(state);
289     alphadev->updateStrokeAdjust(state);
290 }
291 void BitmapOutputDev::updateFillColorSpace(GfxState *state)
292 {
293     rgbdev->updateFillColorSpace(state);
294     alphadev->updateFillColorSpace(state);
295 }
296 void BitmapOutputDev::updateStrokeColorSpace(GfxState *state)
297 {
298     rgbdev->updateStrokeColorSpace(state);
299     alphadev->updateStrokeColorSpace(state);
300 }
301 void BitmapOutputDev::updateFillColor(GfxState *state)
302 {
303     rgbdev->updateFillColor(state);
304     alphadev->updateFillColor(state);
305 }
306 void BitmapOutputDev::updateStrokeColor(GfxState *state)
307 {
308     rgbdev->updateStrokeColor(state);
309     alphadev->updateStrokeColor(state);
310 }
311 void BitmapOutputDev::updateBlendMode(GfxState *state)
312 {
313     rgbdev->updateBlendMode(state);
314     alphadev->updateBlendMode(state);
315 }
316 void BitmapOutputDev::updateFillOpacity(GfxState *state)
317 {
318     rgbdev->updateFillOpacity(state);
319     alphadev->updateFillOpacity(state);
320 }
321 void BitmapOutputDev::updateStrokeOpacity(GfxState *state)
322 {
323     rgbdev->updateStrokeOpacity(state);
324     alphadev->updateStrokeOpacity(state);
325 }
326 void BitmapOutputDev::updateFillOverprint(GfxState *state)
327 {
328     rgbdev->updateFillOverprint(state);
329     alphadev->updateFillOverprint(state);
330 }
331 void BitmapOutputDev::updateStrokeOverprint(GfxState *state)
332 {
333     rgbdev->updateStrokeOverprint(state);
334     alphadev->updateStrokeOverprint(state);
335 }
336 void BitmapOutputDev::updateTransfer(GfxState *state)
337 {
338     rgbdev->updateTransfer(state);
339     alphadev->updateTransfer(state);
340 }
341 void BitmapOutputDev::updateFont(GfxState *state)
342 {
343     rgbdev->updateFont(state);
344     alphadev->updateFont(state);
345     gfxdev->updateFont(state);
346 }
347 void BitmapOutputDev::updateTextMat(GfxState *state)
348 {
349     rgbdev->updateTextMat(state);
350     alphadev->updateTextMat(state);
351     gfxdev->updateTextMat(state);
352 }
353 void BitmapOutputDev::updateCharSpace(GfxState *state)
354 {
355     rgbdev->updateCharSpace(state);
356     alphadev->updateCharSpace(state);
357     gfxdev->updateTextMat(state);
358 }
359 void BitmapOutputDev::updateRender(GfxState *state)
360 {
361     rgbdev->updateRender(state);
362     alphadev->updateRender(state);
363     gfxdev->updateTextMat(state);
364 }
365 void BitmapOutputDev::updateRise(GfxState *state)
366 {
367     rgbdev->updateRise(state);
368     alphadev->updateRise(state);
369     gfxdev->updateTextMat(state);
370 }
371 void BitmapOutputDev::updateWordSpace(GfxState *state)
372 {
373     rgbdev->updateWordSpace(state);
374     alphadev->updateWordSpace(state);
375     gfxdev->updateTextMat(state);
376 }
377 void BitmapOutputDev::updateHorizScaling(GfxState *state)
378 {
379     rgbdev->updateHorizScaling(state);
380     alphadev->updateHorizScaling(state);
381     gfxdev->updateTextMat(state);
382 }
383 void BitmapOutputDev::updateTextPos(GfxState *state)
384 {
385     rgbdev->updateTextPos(state);
386     alphadev->updateTextPos(state);
387     gfxdev->updateTextMat(state);
388 }
389 void BitmapOutputDev::updateTextShift(GfxState *state, double shift)
390 {
391     rgbdev->updateTextShift(state, shift);
392     alphadev->updateTextShift(state, shift);
393     gfxdev->updateTextMat(state);
394 }
395
396 void BitmapOutputDev::stroke(GfxState *state)
397 {
398     msg("<verbose> stroke");
399     rgbdev->stroke(state);
400     alphadev->stroke(state);
401 }
402 void BitmapOutputDev::fill(GfxState *state)
403 {
404     msg("<verbose> fill");
405     rgbdev->fill(state);
406     alphadev->fill(state);
407 }
408 void BitmapOutputDev::eoFill(GfxState *state)
409 {
410     msg("<verbose> eoFill");
411     rgbdev->eoFill(state);
412     alphadev->eoFill(state);
413 }
414 void BitmapOutputDev::tilingPatternFill(GfxState *state, Object *str,
415                                int paintType, Dict *resDict,
416                                double *mat, double *bbox,
417                                int x0, int y0, int x1, int y1,
418                                double xStep, double yStep)
419 {
420     msg("<verbose> tilingPatternFill");
421     rgbdev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
422     alphadev->tilingPatternFill(state, str, paintType, resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
423 }
424 GBool BitmapOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading) 
425 {
426     msg("<verbose> functionShadedFill");
427     rgbdev->functionShadedFill(state, shading);
428     return alphadev->functionShadedFill(state, shading);
429 }
430 GBool BitmapOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading)
431 {
432     msg("<verbose> axialShadedFill");
433     rgbdev->axialShadedFill(state, shading);
434     return alphadev->axialShadedFill(state, shading);
435 }
436 GBool BitmapOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading)
437 {
438     msg("<verbose> radialShadedFill");
439     rgbdev->radialShadedFill(state, shading);
440     return alphadev->radialShadedFill(state, shading);
441 }
442 void BitmapOutputDev::clip(GfxState *state)
443 {
444     msg("<verbose> clip");
445     rgbdev->clip(state);
446     alphadev->clip(state);
447 }
448 void BitmapOutputDev::eoClip(GfxState *state)
449 {
450     msg("<verbose> eoClip");
451     rgbdev->eoClip(state);
452     alphadev->eoClip(state);
453 }
454 void BitmapOutputDev::clipToStrokePath(GfxState *state)
455 {
456     msg("<verbose> clipToStrokePath");
457     rgbdev->clipToStrokePath(state);
458     alphadev->clipToStrokePath(state);
459 }
460
461 void BitmapOutputDev::beginStringOp(GfxState *state)
462 {
463     msg("<verbose> beginStringOp");
464     if(this->config_bitmapfonts) {
465         rgbdev->beginStringOp(state);
466         alphadev->beginStringOp(state);
467     } else {
468         gfxdev->beginStringOp(state);
469     }
470 }
471 void BitmapOutputDev::endStringOp(GfxState *state)
472 {
473     msg("<verbose> endStringOp");
474     if(this->config_bitmapfonts) {
475         rgbdev->endStringOp(state);
476         alphadev->endStringOp(state);
477     } else {
478         gfxdev->endStringOp(state);
479     }
480 }
481 void BitmapOutputDev::beginString(GfxState *state, GString *s)
482 {
483     msg("<verbose> beginString");
484     if(this->config_bitmapfonts) {
485         rgbdev->beginString(state, s);
486         alphadev->beginString(state, s);
487     } else {
488         gfxdev->beginString(state, s);
489     }
490 }
491 void BitmapOutputDev::endString(GfxState *state)
492 {
493     msg("<verbose> endString");
494     if(this->config_bitmapfonts) {
495         rgbdev->endString(state);
496         alphadev->endString(state);
497     } else {
498         gfxdev->endString(state);
499     }
500 }
501 void BitmapOutputDev::drawChar(GfxState *state, double x, double y,
502                       double dx, double dy,
503                       double originX, double originY,
504                       CharCode code, int nBytes, Unicode *u, int uLen)
505 {
506     msg("<verbose> drawChar");
507     flush();
508     if(this->config_bitmapfonts) {
509         rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
510         alphadev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
511     } else {
512         gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
513     }
514 }
515 void BitmapOutputDev::drawString(GfxState *state, GString *s)
516 {
517     msg("<verbose> drawString");
518     if(this->config_bitmapfonts) {
519         rgbdev->drawString(state, s);
520         alphadev->drawString(state, s);
521     } else {
522         gfxdev->drawString(state, s);
523     }
524 }
525 void BitmapOutputDev::endTextObject(GfxState *state)
526 {
527     msg("<verbose> endTextObject");
528     if(this->config_bitmapfonts) {
529         rgbdev->endTextObject(state);
530         alphadev->endTextObject(state);
531     } else {
532         gfxdev->endType3Char(state);
533     }
534 }
535 GBool BitmapOutputDev::beginType3Char(GfxState *state, double x, double y,
536                              double dx, double dy,
537                              CharCode code, Unicode *u, int uLen)
538 {
539     msg("<verbose> beginType3Char");
540     if(this->config_bitmapfonts) {
541         rgbdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
542         return alphadev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
543     } else {
544         return gfxdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
545     }
546 }
547 void BitmapOutputDev::type3D0(GfxState *state, double wx, double wy)
548 {
549     msg("<verbose> type3D0");
550     if(this->config_bitmapfonts) {
551         rgbdev->type3D0(state, wx, wy);
552         alphadev->type3D0(state, wx, wy);
553     } else {
554         return gfxdev->type3D0(state, wx, wy);
555     }
556 }
557 void BitmapOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury)
558 {
559     msg("<verbose> type3D1");
560     if(this->config_bitmapfonts) {
561         rgbdev->type3D1(state, wx, wy, llx, lly, urx, ury);
562         alphadev->type3D1(state, wx, wy, llx, lly, urx, ury);
563     } else {
564         return gfxdev->type3D1(state, wx, wy, llx, lly, urx, ury);
565     }
566 }
567 void BitmapOutputDev::endType3Char(GfxState *state)
568 {
569     msg("<verbose> endType3Char");
570     if(this->config_bitmapfonts) {
571         rgbdev->endType3Char(state);
572         alphadev->endType3Char(state);
573     } else {
574         gfxdev->endType3Char(state);
575     }
576 }
577 void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
578                            int width, int height, GBool invert,
579                            GBool inlineImg)
580 {
581     msg("<verbose> drawImageMask");
582     rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
583     alphadev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
584 }
585 void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
586                        int width, int height, GfxImageColorMap *colorMap,
587                        int *maskColors, GBool inlineImg)
588 {
589     msg("<verbose> drawImage");
590     rgbdev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
591     alphadev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
592 }
593 void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
594                              int width, int height,
595                              GfxImageColorMap *colorMap,
596                              Stream *maskStr, int maskWidth, int maskHeight,
597                              GBool maskInvert)
598 {
599     msg("<verbose> drawMaskedImage");
600     rgbdev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
601     alphadev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
602 }
603 void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
604                                  int width, int height,
605                                  GfxImageColorMap *colorMap,
606                                  Stream *maskStr,
607                                  int maskWidth, int maskHeight,
608                                  GfxImageColorMap *maskColorMap)
609 {
610     msg("<verbose> drawSoftMaskedImage");
611     rgbdev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
612     alphadev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
613 }
614 void BitmapOutputDev::drawForm(Ref id)
615 {
616     msg("<verbose> drawForm");
617     rgbdev->drawForm(id);
618     alphadev->drawForm(id);
619 }
620 void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
621                                     GfxColorSpace *blendingColorSpace,
622                                     GBool isolated, GBool knockout,
623                                     GBool forSoftMask)
624 {
625     msg("<verbose> beginTransparencyGroup");
626     rgbdev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
627     alphadev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
628 }
629 void BitmapOutputDev::endTransparencyGroup(GfxState *state)
630 {
631     msg("<verbose> endTransparencyGroup");
632     rgbdev->endTransparencyGroup(state);
633     alphadev->endTransparencyGroup(state);
634 }
635 void BitmapOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
636 {
637     msg("<verbose> paintTransparencyGroup");
638     rgbdev->paintTransparencyGroup(state,bbox);
639     alphadev->paintTransparencyGroup(state,bbox);
640 }
641 void BitmapOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor)
642 {
643     msg("<verbose> setSoftMask");
644     rgbdev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
645     alphadev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
646 }
647 void BitmapOutputDev::clearSoftMask(GfxState *state)
648 {
649     msg("<verbose> clearSoftMask");
650     rgbdev->clearSoftMask(state);
651     alphadev->clearSoftMask(state);
652 }