3 Output Device which creates a bitmap.
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.
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.
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 */
22 #include "BitmapOutputDev.h"
23 #include "GFXOutputDev.h"
24 #include "SplashBitmap.h"
27 static SplashColor splash_white = {255,255,255};
28 static SplashColor splash_black = {255,255,255};
30 BitmapOutputDev::BitmapOutputDev(InfoOutputDev*info, PDFDoc*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());
42 this->config_bitmapfonts = 0;
44 BitmapOutputDev::~BitmapOutputDev()
48 void BitmapOutputDev::setDevice(gfxdevice_t*dev)
51 this->gfxdev->setDevice(dev);
53 void BitmapOutputDev::setMove(int x,int y)
56 void BitmapOutputDev::setClip(int x1,int y1,int x2,int y2)
59 void BitmapOutputDev::setParameter(const char*key, const char*value)
62 void BitmapOutputDev::preparePage(int pdfpage, int outputpage)
66 void getBitmapBBox(Guchar*alpha, int width, int height, int*xmin, int*ymin, int*xmax, int*ymax)
72 for(y=0;y<height;y++) {
73 Guchar*a = &alpha[y*width];
74 for(x=0;x<width;x++) {
77 int left = x; //first occupied pixel from left
78 int right = x+1; //last non-occupied pixel from right
87 if(left<*xmin) *xmin = left;
88 if(right>*xmax) *xmax = right;
91 if(*xmin>=*xmax || *ymin>=*ymax) {
99 void BitmapOutputDev::flush()
101 int width = rgbdev->getBitmapWidth();
102 int height = rgbdev->getBitmapHeight();
103 SplashColorPtr rgb = rgbdev->getBitmap()->getDataPtr();
104 Guchar*alpha = rgbdev->getBitmap()->getAlphaPtr();
106 int xmin,ymin,xmax,ymax;
107 getBitmapBBox(alpha, width, height, &xmin,&ymin,&xmax,&ymax);
109 msg("<verbose> Flushing graphics (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax);
111 if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do
114 if(sizeof(SplashColor)!=3) {
115 msg("<error> sizeof(SplashColor)!=3");
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);
127 img->height = rangey;
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];
147 gfxline_t* line = gfxline_makerectangle(xmin, ymin, xmax, ymax);
148 dev->fillbitmap(dev, line, img, &m, 0);
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));
154 free(img->data);img->data=0;free(img);img=0;
157 void BitmapOutputDev::startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2)
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);
166 void BitmapOutputDev::endPage()
168 msg("<verbose> endPage");
171 /* splash will now destroy alpha, and paint the
172 background color into the "holes" in the bitmap */
177 GBool BitmapOutputDev::upsideDown()
179 rgbdev->upsideDown();
180 return alphadev->upsideDown();
183 GBool BitmapOutputDev::useDrawChar()
185 rgbdev->useDrawChar();
186 return alphadev->useDrawChar();
189 GBool BitmapOutputDev::useTilingPatternFill()
191 rgbdev->useTilingPatternFill();
192 return alphadev->useTilingPatternFill();
195 GBool BitmapOutputDev::useShadedFills()
197 rgbdev->useTilingPatternFill();
198 return alphadev->useTilingPatternFill();
201 GBool BitmapOutputDev::useDrawForm()
203 rgbdev->useDrawForm();
204 return alphadev->useDrawForm();
207 GBool BitmapOutputDev::interpretType3Chars()
209 if(config_bitmapfonts) {
210 rgbdev->interpretType3Chars();
211 return alphadev->interpretType3Chars();
213 return gfxdev->interpretType3Chars();
217 GBool BitmapOutputDev::needNonText()
219 rgbdev->needNonText();
220 return alphadev->needNonText();
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)
231 void BitmapOutputDev::setDefaultCTM(double *ctm)
233 rgbdev->setDefaultCTM(ctm);
234 alphadev->setDefaultCTM(ctm);
236 void BitmapOutputDev::saveState(GfxState *state)
238 rgbdev->saveState(state);
239 alphadev->saveState(state);
241 void BitmapOutputDev::restoreState(GfxState *state)
243 rgbdev->restoreState(state);
244 alphadev->restoreState(state);
246 void BitmapOutputDev::updateAll(GfxState *state)
248 rgbdev->updateAll(state);
249 alphadev->updateAll(state);
251 void BitmapOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32)
253 rgbdev->updateCTM(state,m11,m12,m21,m22,m31,m32);
254 alphadev->updateCTM(state,m11,m12,m21,m22,m31,m32);
256 void BitmapOutputDev::updateLineDash(GfxState *state)
258 rgbdev->updateLineDash(state);
259 alphadev->updateLineDash(state);
261 void BitmapOutputDev::updateFlatness(GfxState *state)
263 rgbdev->updateFlatness(state);
264 alphadev->updateFlatness(state);
266 void BitmapOutputDev::updateLineJoin(GfxState *state)
268 rgbdev->updateLineJoin(state);
269 alphadev->updateLineJoin(state);
271 void BitmapOutputDev::updateLineCap(GfxState *state)
273 rgbdev->updateLineCap(state);
274 alphadev->updateLineCap(state);
276 void BitmapOutputDev::updateMiterLimit(GfxState *state)
278 rgbdev->updateMiterLimit(state);
279 alphadev->updateMiterLimit(state);
281 void BitmapOutputDev::updateLineWidth(GfxState *state)
283 rgbdev->updateLineWidth(state);
284 alphadev->updateLineWidth(state);
286 void BitmapOutputDev::updateStrokeAdjust(GfxState *state)
288 rgbdev->updateStrokeAdjust(state);
289 alphadev->updateStrokeAdjust(state);
291 void BitmapOutputDev::updateFillColorSpace(GfxState *state)
293 rgbdev->updateFillColorSpace(state);
294 alphadev->updateFillColorSpace(state);
296 void BitmapOutputDev::updateStrokeColorSpace(GfxState *state)
298 rgbdev->updateStrokeColorSpace(state);
299 alphadev->updateStrokeColorSpace(state);
301 void BitmapOutputDev::updateFillColor(GfxState *state)
303 rgbdev->updateFillColor(state);
304 alphadev->updateFillColor(state);
306 void BitmapOutputDev::updateStrokeColor(GfxState *state)
308 rgbdev->updateStrokeColor(state);
309 alphadev->updateStrokeColor(state);
311 void BitmapOutputDev::updateBlendMode(GfxState *state)
313 rgbdev->updateBlendMode(state);
314 alphadev->updateBlendMode(state);
316 void BitmapOutputDev::updateFillOpacity(GfxState *state)
318 rgbdev->updateFillOpacity(state);
319 alphadev->updateFillOpacity(state);
321 void BitmapOutputDev::updateStrokeOpacity(GfxState *state)
323 rgbdev->updateStrokeOpacity(state);
324 alphadev->updateStrokeOpacity(state);
326 void BitmapOutputDev::updateFillOverprint(GfxState *state)
328 rgbdev->updateFillOverprint(state);
329 alphadev->updateFillOverprint(state);
331 void BitmapOutputDev::updateStrokeOverprint(GfxState *state)
333 rgbdev->updateStrokeOverprint(state);
334 alphadev->updateStrokeOverprint(state);
336 void BitmapOutputDev::updateTransfer(GfxState *state)
338 rgbdev->updateTransfer(state);
339 alphadev->updateTransfer(state);
341 void BitmapOutputDev::updateFont(GfxState *state)
343 rgbdev->updateFont(state);
344 alphadev->updateFont(state);
345 gfxdev->updateFont(state);
347 void BitmapOutputDev::updateTextMat(GfxState *state)
349 rgbdev->updateTextMat(state);
350 alphadev->updateTextMat(state);
351 gfxdev->updateTextMat(state);
353 void BitmapOutputDev::updateCharSpace(GfxState *state)
355 rgbdev->updateCharSpace(state);
356 alphadev->updateCharSpace(state);
357 gfxdev->updateTextMat(state);
359 void BitmapOutputDev::updateRender(GfxState *state)
361 rgbdev->updateRender(state);
362 alphadev->updateRender(state);
363 gfxdev->updateTextMat(state);
365 void BitmapOutputDev::updateRise(GfxState *state)
367 rgbdev->updateRise(state);
368 alphadev->updateRise(state);
369 gfxdev->updateTextMat(state);
371 void BitmapOutputDev::updateWordSpace(GfxState *state)
373 rgbdev->updateWordSpace(state);
374 alphadev->updateWordSpace(state);
375 gfxdev->updateTextMat(state);
377 void BitmapOutputDev::updateHorizScaling(GfxState *state)
379 rgbdev->updateHorizScaling(state);
380 alphadev->updateHorizScaling(state);
381 gfxdev->updateTextMat(state);
383 void BitmapOutputDev::updateTextPos(GfxState *state)
385 rgbdev->updateTextPos(state);
386 alphadev->updateTextPos(state);
387 gfxdev->updateTextMat(state);
389 void BitmapOutputDev::updateTextShift(GfxState *state, double shift)
391 rgbdev->updateTextShift(state, shift);
392 alphadev->updateTextShift(state, shift);
393 gfxdev->updateTextMat(state);
396 void BitmapOutputDev::stroke(GfxState *state)
398 msg("<verbose> stroke");
399 rgbdev->stroke(state);
400 alphadev->stroke(state);
402 void BitmapOutputDev::fill(GfxState *state)
404 msg("<verbose> fill");
406 alphadev->fill(state);
408 void BitmapOutputDev::eoFill(GfxState *state)
410 msg("<verbose> eoFill");
411 rgbdev->eoFill(state);
412 alphadev->eoFill(state);
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)
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);
424 GBool BitmapOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading)
426 msg("<verbose> functionShadedFill");
427 rgbdev->functionShadedFill(state, shading);
428 return alphadev->functionShadedFill(state, shading);
430 GBool BitmapOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading)
432 msg("<verbose> axialShadedFill");
433 rgbdev->axialShadedFill(state, shading);
434 return alphadev->axialShadedFill(state, shading);
436 GBool BitmapOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading)
438 msg("<verbose> radialShadedFill");
439 rgbdev->radialShadedFill(state, shading);
440 return alphadev->radialShadedFill(state, shading);
442 void BitmapOutputDev::clip(GfxState *state)
444 msg("<verbose> clip");
446 alphadev->clip(state);
448 void BitmapOutputDev::eoClip(GfxState *state)
450 msg("<verbose> eoClip");
451 rgbdev->eoClip(state);
452 alphadev->eoClip(state);
454 void BitmapOutputDev::clipToStrokePath(GfxState *state)
456 msg("<verbose> clipToStrokePath");
457 rgbdev->clipToStrokePath(state);
458 alphadev->clipToStrokePath(state);
461 void BitmapOutputDev::beginStringOp(GfxState *state)
463 msg("<verbose> beginStringOp");
464 if(this->config_bitmapfonts) {
465 rgbdev->beginStringOp(state);
466 alphadev->beginStringOp(state);
468 gfxdev->beginStringOp(state);
471 void BitmapOutputDev::endStringOp(GfxState *state)
473 msg("<verbose> endStringOp");
474 if(this->config_bitmapfonts) {
475 rgbdev->endStringOp(state);
476 alphadev->endStringOp(state);
478 gfxdev->endStringOp(state);
481 void BitmapOutputDev::beginString(GfxState *state, GString *s)
483 msg("<verbose> beginString");
484 if(this->config_bitmapfonts) {
485 rgbdev->beginString(state, s);
486 alphadev->beginString(state, s);
488 gfxdev->beginString(state, s);
491 void BitmapOutputDev::endString(GfxState *state)
493 msg("<verbose> endString");
494 if(this->config_bitmapfonts) {
495 rgbdev->endString(state);
496 alphadev->endString(state);
498 gfxdev->endString(state);
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)
506 msg("<verbose> drawChar");
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);
512 gfxdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
515 void BitmapOutputDev::drawString(GfxState *state, GString *s)
517 msg("<verbose> drawString");
518 if(this->config_bitmapfonts) {
519 rgbdev->drawString(state, s);
520 alphadev->drawString(state, s);
522 gfxdev->drawString(state, s);
525 void BitmapOutputDev::endTextObject(GfxState *state)
527 msg("<verbose> endTextObject");
528 if(this->config_bitmapfonts) {
529 rgbdev->endTextObject(state);
530 alphadev->endTextObject(state);
532 gfxdev->endType3Char(state);
535 GBool BitmapOutputDev::beginType3Char(GfxState *state, double x, double y,
536 double dx, double dy,
537 CharCode code, Unicode *u, int uLen)
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);
544 return gfxdev->beginType3Char(state, x, y, dx, dy, code, u, uLen);
547 void BitmapOutputDev::type3D0(GfxState *state, double wx, double wy)
549 msg("<verbose> type3D0");
550 if(this->config_bitmapfonts) {
551 rgbdev->type3D0(state, wx, wy);
552 alphadev->type3D0(state, wx, wy);
554 return gfxdev->type3D0(state, wx, wy);
557 void BitmapOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury)
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);
564 return gfxdev->type3D1(state, wx, wy, llx, lly, urx, ury);
567 void BitmapOutputDev::endType3Char(GfxState *state)
569 msg("<verbose> endType3Char");
570 if(this->config_bitmapfonts) {
571 rgbdev->endType3Char(state);
572 alphadev->endType3Char(state);
574 gfxdev->endType3Char(state);
577 void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
578 int width, int height, GBool invert,
581 msg("<verbose> drawImageMask");
582 rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
583 alphadev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
585 void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
586 int width, int height, GfxImageColorMap *colorMap,
587 int *maskColors, GBool inlineImg)
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);
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,
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);
603 void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
604 int width, int height,
605 GfxImageColorMap *colorMap,
607 int maskWidth, int maskHeight,
608 GfxImageColorMap *maskColorMap)
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);
614 void BitmapOutputDev::drawForm(Ref id)
616 msg("<verbose> drawForm");
617 rgbdev->drawForm(id);
618 alphadev->drawForm(id);
620 void BitmapOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
621 GfxColorSpace *blendingColorSpace,
622 GBool isolated, GBool knockout,
625 msg("<verbose> beginTransparencyGroup");
626 rgbdev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
627 alphadev->beginTransparencyGroup(state, bbox, blendingColorSpace, isolated, knockout, forSoftMask);
629 void BitmapOutputDev::endTransparencyGroup(GfxState *state)
631 msg("<verbose> endTransparencyGroup");
632 rgbdev->endTransparencyGroup(state);
633 alphadev->endTransparencyGroup(state);
635 void BitmapOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
637 msg("<verbose> paintTransparencyGroup");
638 rgbdev->paintTransparencyGroup(state,bbox);
639 alphadev->paintTransparencyGroup(state,bbox);
641 void BitmapOutputDev::setSoftMask(GfxState *state, double *bbox, GBool alpha, Function *transferFunc, GfxColor *backdropColor)
643 msg("<verbose> setSoftMask");
644 rgbdev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
645 alphadev->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
647 void BitmapOutputDev::clearSoftMask(GfxState *state)
649 msg("<verbose> clearSoftMask");
650 rgbdev->clearSoftMask(state);
651 alphadev->clearSoftMask(state);