/* * PostScript driver bitmap functions * * Copyright 1998 Huw D M Davies * */ #include "gdi.h" #include "psdrv.h" #include "debugtools.h" #include "bitmap.h" #include "winbase.h" DEFAULT_DEBUG_CHANNEL(psdrv) /*************************************************************************** * PSDRV_WriteImageHeader * * Helper for PSDRV_StretchDIBits * * BUGS * Uses level 2 PostScript */ static BOOL PSDRV_WriteImageHeader(DC *dc, const BITMAPINFO *info, INT xDst, INT yDst, INT widthDst, INT heightDst, INT widthSrc, INT heightSrc) { COLORREF map[256]; int i; switch(info->bmiHeader.biBitCount) { case 8: PSDRV_WriteIndexColorSpaceBegin(dc, 255); for(i = 0; i < 256; i++) { map[i] = info->bmiColors[i].rgbRed | info->bmiColors[i].rgbGreen << 8 | info->bmiColors[i].rgbBlue << 16; } PSDRV_WriteRGB(dc, map, 256); PSDRV_WriteIndexColorSpaceEnd(dc); break; case 4: PSDRV_WriteIndexColorSpaceBegin(dc, 15); for(i = 0; i < 16; i++) { map[i] = info->bmiColors[i].rgbRed | info->bmiColors[i].rgbGreen << 8 | info->bmiColors[i].rgbBlue << 16; } PSDRV_WriteRGB(dc, map, 16); PSDRV_WriteIndexColorSpaceEnd(dc); break; case 1: PSDRV_WriteIndexColorSpaceBegin(dc, 1); for(i = 0; i < 2; i++) { map[i] = info->bmiColors[i].rgbRed | info->bmiColors[i].rgbGreen << 8 | info->bmiColors[i].rgbBlue << 16; } PSDRV_WriteRGB(dc, map, 2); PSDRV_WriteIndexColorSpaceEnd(dc); break; case 15: case 16: case 24: case 32: { PSCOLOR pscol; pscol.type = PSCOLOR_RGB; pscol.value.rgb.r = pscol.value.rgb.g = pscol.value.rgb.b = 0.0; PSDRV_WriteSetColor(dc, &pscol); break; } default: FIXME("Not implemented yet\n"); return FALSE; break; } PSDRV_WriteImageDict(dc, info->bmiHeader.biBitCount, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc, NULL); return TRUE; } /*************************************************************************** * * PSDRV_StretchDIBits * * BUGS * Doesn't work correctly if xSrc isn't byte aligned - this affects 1 and 4 * bit depths. * Compression not implemented. */ INT PSDRV_StretchDIBits( DC *dc, INT xDst, INT yDst, INT widthDst, INT heightDst, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits, const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) { DWORD fullSrcWidth; INT widthbytes, fullSrcHeight; WORD bpp, compression; const char *ptr; INT line; TRACE("%08x (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dc->hSelf, xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst); DIB_GetBitmapInfo((const BITMAPINFOHEADER *)info, &fullSrcWidth, &fullSrcHeight, &bpp, &compression); widthbytes = DIB_GetDIBWidthBytes(fullSrcWidth, bpp); TRACE("full size=%ldx%d bpp=%d compression=%d\n", fullSrcWidth, fullSrcHeight, bpp, compression); if(compression != BI_RGB) { FIXME("Compression not supported\n"); return FALSE; } xDst = XLPTODP(dc, xDst); yDst = YLPTODP(dc, yDst); widthDst = XLSTODS(dc, widthDst); heightDst = YLSTODS(dc, heightDst); switch(bpp) { case 1: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); if(xSrc & 7) FIXME("This won't work...\n"); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteBytes(dc, ptr + xSrc/8, (widthSrc+7)/8); break; case 4: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); if(xSrc & 1) FIXME("This won't work...\n"); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteBytes(dc, ptr + xSrc/2, (widthSrc+1)/2); break; case 8: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteBytes(dc, ptr + xSrc, widthSrc); break; case 15: case 16: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteDIBits16(dc, (WORD *)ptr + xSrc, widthSrc); break; case 24: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteDIBits24(dc, ptr + xSrc * 3, widthSrc); break; case 32: PSDRV_WriteGSave(dc); PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc); ptr = bits; ptr += (ySrc * widthbytes); for(line = 0; line < heightSrc; line++, ptr += widthbytes) PSDRV_WriteDIBits32(dc, ptr + xSrc * 3, widthSrc); break; default: FIXME("Unsupported depth\n"); return FALSE; } PSDRV_WriteSpool(dc, "%\n", 2); /* some versions of ghostscript seem to eat one too many chars after the image operator */ PSDRV_WriteGRestore(dc); return TRUE; }