fixed stroke generation in poly2bitmap
[swftools.git] / lib / pdf / BitmapOutputDev.cc
index adc3165..9e8123b 100644 (file)
@@ -214,12 +214,26 @@ void BitmapOutputDev::flushBitmap()
        int ymax = b->ymax;
 
        /* clip against (-movex, -movey, -movex+width, -movey+height) */
-       if(xmin < -this->movex) xmin = -this->movex;
-       if(ymin < -this->movey) ymin = -this->movey;
-       if(xmax > -this->movex + width) xmax = -this->movex+this->width;
-       if(ymax > -this->movey + height) ymax = -this->movey+this->height;
 
-       msg("<verbose> Flushing bitmap (bbox: %d,%d,%d,%d)", xmin,ymin,xmax,ymax);
+       msg("<verbose> Flushing bitmap (bbox: %d,%d,%d,%d %dx%d) (clipped against %d,%d,%d,%d)", xmin,ymin,xmax,ymax, xmax-xmin, ymax-ymin,
+               -this->movex, -this->movey, -this->movex+this->width, -this->movey+this->height);
+
+       if(xmin < -this->movex) {
+           xmin = -this->movex;
+           if(xmax < -this->movex) continue;
+       }
+       if(ymin < -this->movey) {
+           ymin = -this->movey;
+           if(ymax < -this->movey) continue;
+       }
+       if(xmax >= -this->movex + this->width) {
+           xmax = -this->movex+this->width;
+           if(xmin >= -this->movex + this->width) continue;
+       }
+       if(ymax >= -this->movey + this->height) {
+           ymax = -this->movey+this->height;
+           if(ymin >= -this->movey + this->height) continue;
+       }
        
        if((xmax-xmin)<=0 || (ymax-ymin)<=0) // no bitmap, nothing to do
            continue;
@@ -454,16 +468,49 @@ static void update_bitmap(SplashBitmap*bitmap, SplashBitmap*update, int x1, int
     if(!fixBBox(&x1, &y1, &x2, &y2, bitmap->getWidth(), bitmap->getHeight()))
        return;
     
-    Guchar*b = bitmap->getDataPtr() + y1*width8;
-    Guchar*u = update->getDataPtr() + y1*width8;
+    Guchar*b = bitmap->getDataPtr() + y1*width8 + x1/8;
+    Guchar*u = update->getDataPtr() + y1*width8 + x1/8;
+    int yspan = y2-y1;
+    int xspan = (x2+7)/8 - x1/8;
     int size = (y2-y1)*width8;
 
     if(overwrite) {
-       memcpy(b, u, size);
+       int y;
+       for(y=0;y<yspan;y++) {
+           memcpy(b, u, xspan);
+           b += width8;
+           u += width8;
+       }
     } else {
-       int t;
-       for(t=0;t<size;t++) {
-           b[t] |= u[t];
+       if(((ptroff_t)b&7)==((ptroff_t)u&7)) {
+           int x,y;
+           for(y=0;y<yspan;y++) {
+               Guchar*e1 = b+xspan-8;
+               Guchar*e2 = b+xspan;
+               while(((ptroff_t)b&7) && b<e1) {
+                   *b |= *u;
+                   b++;u++;
+               }
+               while(b<e1) {
+                   *(long long*)b |= *(long long*)u;
+                   b+=8;u+=8;
+               }
+               while(b<e2) {
+                   *b |= *u;
+                   b++;u++;
+               }
+               b += width8-xspan;
+               u += width8-xspan;
+           }
+       } else {
+           int x,y;
+           for(y=0;y<yspan;y++) {
+               for(x=0;x<xspan;x++) {
+                   b[x] |= u[x];
+               }
+               b += width8;
+               u += width8;
+           }
        }
     }
 }
@@ -664,7 +711,7 @@ GBool compare8(unsigned char*data1, unsigned char*data2, int len)
     if(!len)
         return 0;
     if(((ptroff_t)data1&7)==((ptroff_t)data2&7)) {
-        // oh good, we can do aligning
+        // oh good, we can align both to 8 byte
         while((ptroff_t)data1&7) {
             if(*data1&*data2)
                 return 1;
@@ -811,7 +858,6 @@ void BitmapOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, do
     this->width = (int)(x2-x1);
     this->height = (int)(y2-y1);
 
-    msg("<debug> startPage");
     rgbdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
     boolpolydev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
     booltextdev->startPage(pageNum, state, crop_x1, crop_y1, crop_x2, crop_y2);
@@ -826,6 +872,8 @@ void BitmapOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, do
     booltextbitmap = booltextdev->getBitmap();
     staletextbitmap = new SplashBitmap(booltextbitmap->getWidth(), booltextbitmap->getHeight(), 1, booltextbitmap->getMode(), 0);
     assert(staletextbitmap->getRowSize() == booltextbitmap->getRowSize());
+    
+    msg("<debug> startPage %dx%d (%dx%d)", this->width, this->height, booltextbitmap->getWidth(), booltextbitmap->getHeight());
 
     clip0bitmap = clip0dev->getBitmap();
     clip1bitmap = clip1dev->getBitmap();
@@ -1426,6 +1474,10 @@ void BitmapOutputDev::drawChar(GfxState *state, double x, double y,
         boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
         booltextdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
         clip1dev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
+    } else if(state->getRender()&RENDER_STROKE) {
+       // we're drawing as stroke
+       boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
+       rgbdev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
     } else if(rgbbitmap != rgbdev->getBitmap()) {
        // we're doing softmasking or transparency grouping
        boolpolydev->drawChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen);
@@ -1611,17 +1663,15 @@ void BitmapOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
                           GBool inlineImg)
 {
     msg("<debug> drawImageMask streamkind=%d", str->getKind());
-    CopyStream*cpystr = 0;
-    if(inlineImg) {
-       cpystr = new CopyStream(str, height * ((width + 7) / 8));
-       str = cpystr->getStream();
-    }
+
+    CopyStream*cpystr = new CopyStream(str, height * ((width + 7) / 8));
+    str = cpystr->getStream();
+    
     boolpolydev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
     gfxbbox_t bbox = getImageBBox(state);
     checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
     rgbdev->drawImageMask(state, ref, str, width, height, invert, inlineImg);
-    if(cpystr)
-       delete cpystr;
+    delete cpystr;
     dbg_newdata("imagemask");
 }
 void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
@@ -1629,17 +1679,15 @@ void BitmapOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
                       int *maskColors, GBool inlineImg)
 {
     msg("<debug> drawImage streamkind=%d", str->getKind());
-    CopyStream*cpystr = 0;
-    if(inlineImg) {
-       cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
-       str = cpystr->getStream();
-    }
+       
+    CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+    str = cpystr->getStream();
+
     boolpolydev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
     gfxbbox_t bbox=getImageBBox(state);
     checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
     rgbdev->drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
-    if(cpystr)
-       delete cpystr;
+    delete cpystr;
     dbg_newdata("image");
 }
 void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -1649,10 +1697,15 @@ void BitmapOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
                             GBool maskInvert)
 {
     msg("<debug> drawMaskedImage streamkind=%d", str->getKind());
+    
+    CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+    str = cpystr->getStream();
+
     boolpolydev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
     gfxbbox_t bbox=getImageBBox(state);
     checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
     rgbdev->drawMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert);
+    delete cpystr;
     dbg_newdata("maskedimage");
 }
 void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -1663,10 +1716,15 @@ void BitmapOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *
                                 GfxImageColorMap *maskColorMap)
 {
     msg("<debug> drawSoftMaskedImage %dx%d (%dx%d) streamkind=%d", width, height, maskWidth, maskHeight, str->getKind());
+
+    CopyStream*cpystr = new CopyStream(str, height * ((width * colorMap->getNumPixelComps() * colorMap->getBits() + 7) / 8));
+    str = cpystr->getStream();
+
     boolpolydev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
     gfxbbox_t bbox=getImageBBox(state);
     checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
     rgbdev->drawSoftMaskedImage(state, ref, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap);
+    delete cpystr;
     dbg_newdata("softmaskimage");
 }
 void BitmapOutputDev::drawForm(Ref id)