--- poppler-0.12.0/poppler/CairoOutputDev.cc 2009-09-02 14:48:16.000000000 -0400 +++ poppler-0.12.0-patched/poppler/CairoOutputDev.cc 2009-12-02 15:51:41.721412311 -0500 @@ -96,6 +96,67 @@ this->image = cairo_surface_reference (image); } +void PrescaleARGB(unsigned int * source,int width,int height,int stride,unsigned int * dest,int scaledWidth,int scaledHeight,int scaledStride) +{ + stride/=4; + scaledStride/=4; + // sanity check + if (scaledHeight>height || scaledWidth>width || scaledHeight<=0 || scaledWidth<=0 || stride>8)&0xFF; + sum3+=(pLine[sx]>>16)&0xFF; + sum4+=pLine[sx]>>24; + } // sum x + pLine+=stride; + } // sum y + pLine=pt+dx; + count=dx*dy; + dest[z++]=sum1/count+(sum2/count<<8)+(sum3/count<<16)+(sum4/count<<24); + } // row + oy+=dy; + } + + delete [] pixelwidth; +} + + //------------------------------------------------------------------------ // CairoOutputDev //------------------------------------------------------------------------ @@ -1963,13 +2024,40 @@ ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB); #endif + int scaledWidth,scaledHeight,scaledStride; + unsigned char * scaledBuffer; + + cairo_get_matrix(cairo, &matrix); + scaledWidth=fabs(matrix.xx+matrix.yx)+0.5; + scaledHeight=fabs(matrix.xy+matrix.yy)+0.5; + + if (printing || scaledWidth>=width || scaledHeight>=height) + { // no prescaling => render directly to cairo_image + scaledWidth=width; + scaledHeight=height; + } + else + { // first render to ARGB buffer then downsample to cairo_image + stride = width*4; + buffer = new unsigned char [stride*height]; + } + image = cairo_image_surface_create (maskColors ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, - width, height); + scaledWidth, scaledHeight); if (cairo_surface_status (image)) goto cleanup; + + scaledBuffer = cairo_image_surface_get_data (image); + scaledStride = cairo_image_surface_get_stride (image); + if (scaledWidth>=width || scaledHeight>=height) + { // no prescaling => render directly to cairo_image + stride = scaledStride; + buffer = scaledBuffer; + } + // special case for one-channel (monochrome/gray/separation) images: // build a lookup table here if (colorMap->getNumPixelComps() == 1) { @@ -1982,11 +2070,9 @@ pix = (Guchar)i; colorMap->getRGB(&pix, &lookup[i]); - } - } + } + } - buffer = cairo_image_surface_get_data (image); - stride = cairo_image_surface_get_stride (image); for (int y = 0; y < height; y++) { uint32_t *dest = (uint32_t *) (buffer + y * stride); Guchar *pix = imgStr->getLine(); @@ -2028,6 +2114,13 @@ } gfree(lookup); + + if (scaledWidth