* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Id$ */
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
-HBITMAP APIENTRY
-IntGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
- IN OPTIONAL LPBYTE pBits)
+LONG APIENTRY
+IntSetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ IN PBYTE Bits)
{
- HBITMAP hBitmap;
- SIZEL Size;
- LONG WidthBytes;
- PSURFACE psurfBmp;
+ /* Don't copy more bytes than the buffer has */
+ Bytes = min(Bytes, psurf->SurfObj.cjBits);
- /* NOTE: Windows also doesn't store nr. of planes separately! */
- BitsPixel = BITMAP_GetRealBitsPixel(BitsPixel * Planes);
+ RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- /* Check parameters */
- if (BitsPixel == 0 || Width <= 0 || Width >= 0x8000000 || Height == 0)
- {
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
+ return Bytes;
+}
- WidthBytes = BITMAP_GetWidthBytes(Width, BitsPixel);
+void
+NTAPI
+UnsafeSetBitmapBits(
+ PSURFACE psurf,
+ IN ULONG cjBits,
+ IN PVOID pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
- Size.cx = Width;
- Size.cy = abs(Height);
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- /* Make sure that cjBits will not overflow */
- if ((ULONGLONG)WidthBytes * Size.cy >= 0x100000000ULL)
- {
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
+ /* Get pointers */
+ pjDst = psurf->SurfObj.pvScan0;
+ pjSrc = pvBits;
+ lDeltaDst = psurf->SurfObj.lDelta;
+ lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
- /* Create the bitmap object. */
- hBitmap = IntCreateBitmap(Size, WidthBytes,
- BitmapFormat(BitsPixel, BI_RGB),
- (Height < 0 ? BMF_TOPDOWN : 0) |
- (NULL == pBits ? 0 : BMF_NOZEROINIT), NULL);
- if (!hBitmap)
+ while (nHeight--)
{
- DPRINT("IntGdiCreateBitmap: returned 0\n");
- return 0;
+ /* Copy one line */
+ memcpy(pjDst, pjSrc, lDeltaSrc);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
}
- psurfBmp = SURFACE_LockSurface(hBitmap);
- if (psurfBmp == NULL)
+}
+
+HBITMAP
+APIENTRY
+GreCreateBitmapEx(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN ULONG cjWidthBytes,
+ IN ULONG iFormat,
+ IN USHORT fjBitmap,
+ IN ULONG cjSizeImage,
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags)
+{
+ PSURFACE psurf;
+ SURFOBJ *pso;
+ HBITMAP hbmp;
+ PVOID pvCompressedBits;
+ SIZEL sizl;
+
+ /* Verify format */
+ if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
+
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
+ if (!psurf)
{
- NtGdiDeleteObject(hBitmap);
+ DPRINT1("SURFACE_AllocSurface failed.\n");
return NULL;
}
- psurfBmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
- psurfBmp->hDC = NULL; // Fixme
+ /* Get the handle for the bitmap and the surfobj */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+ pso = &psurf->SurfObj;
- if (NULL != pBits)
+ /* The infamous RLE hack */
+ if (iFormat == BMF_4RLE || iFormat == BMF_8RLE)
{
- IntSetBitmapBits(psurfBmp, psurfBmp->SurfObj.cjBits, pBits);
+ sizl.cx = nWidth;
+ sizl.cy = nHeight;
+ pvCompressedBits = pvBits;
+ pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
+ DecompressBitmap(sizl, pvCompressedBits, pvBits, pso->lDelta, iFormat);
+ fjBitmap |= BMF_RLE_HACK;
}
- SURFACE_UnlockSurface(psurfBmp);
+ /* Mark as API bitmap */
+ psurf->flags |= (flags | API_BITMAP);
- DPRINT("IntGdiCreateBitmap : %dx%d, %d BPP colors, topdown %d, returning %08x\n",
- Size.cx, Size.cy, BitsPixel, (Height < 0 ? 1 : 0), hBitmap);
+ /* Set the bitmap bits */
+ if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
+ {
+ /* Bail out if that failed */
+ DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ return NULL;
+ }
- return hBitmap;
+ /* Unlock the surface and return */
+ SURFACE_UnlockSurface(psurf);
+ return hbmp;
}
+/* Creates a DDB surface,
+ * as in CreateCompatibleBitmap or CreateBitmap.
+ */
+HBITMAP
+APIENTRY
+GreCreateBitmap(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
+ IN OPTIONAL PVOID pvBits)
+{
+ /* Call the extended function */
+ return GreCreateBitmapEx(nWidth,
+ nHeight,
+ 0, /* auto width */
+ BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
+ 0, /* no bitmap flags */
+ 0, /* auto size */
+ pvBits,
+ DDB_SURFACE /* DDB */);
+}
-HBITMAP APIENTRY
+HBITMAP
+APIENTRY
NtGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
{
- if (pUnsafeBits)
+ HBITMAP hbmp;
+ ULONG cjWidthBytes, iFormat;
+
+ /* NOTE: Windows also doesn't store nr. of planes separately! */
+ cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes);
+
+ /* Calculate bitmap format */
+ iFormat = BitmapFormat(cBitsPixel, BI_RGB);
+
+ /* Check parameters */
+ if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0)
+ {
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* Make sure that cjBits will not overflow */
+ cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+ if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
{
- BOOL Hit = FALSE;
- UINT cjBits = BITMAP_GetWidthBytes(Width, BitsPixel) * abs(Height);
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* cBitsPixel = cBitsPixel * cPlanes now! */
+ hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL);
- // FIXME: Use MmSecureVirtualMemory
+ if (pUnsafeBits)
+ {
+ PSURFACE psurf = SURFACE_LockSurface(hbmp);
_SEH2_TRY
{
- ProbeForRead(pUnsafeBits, cjBits, 1);
+ ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
+ UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ _SEH2_YIELD(return NULL;)
}
_SEH2_END
- if (Hit) return 0;
+ SURFACE_UnlockSurface(psurf);
}
- return IntGdiCreateBitmap(Width, Height, Planes, BitsPixel, pUnsafeBits);
+ return hbmp;
}
+
HBITMAP FASTCALL
IntCreateCompatibleBitmap(
PDC Dc,
{
if (Dc->dctype != DC_TYPE_MEMORY)
{
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- IntGdiGetDeviceCaps(Dc,PLANES),
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),
- NULL);
+ PSURFACE psurf;
+
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ Dc->ppdev->gdiinfo.cBitsPixel,
+ NULL);
+ psurf = SURFACE_LockSurface(Bmp);
+ ASSERT(psurf);
+ /* Set palette */
+ psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+ /* Set flags */
+ psurf->flags = API_BITMAP;
+ psurf->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurf);
}
else
{
DIBSECTION dibs;
INT Count;
- PSURFACE psurf = SURFACE_LockSurface(Dc->rosdc.hBitmap);
+ PSURFACE psurf = Dc->dclevel.pSurface;
Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
if (Count)
{
if (Count == sizeof(BITMAP))
{
- /* We have a bitmap bug!!! W/O the HACK, we have white icons.
-
- MSDN Note: When a memory device context is created, it initially
- has a 1-by-1 monochrome bitmap selected into it. If this memory
- device context is used in CreateCompatibleBitmap, the bitmap that
- is created is a monochrome bitmap. To create a color bitmap, use
- the hDC that was used to create the memory device context, as
- shown in the following code:
-
- HDC memDC = CreateCompatibleDC(hDC);
- HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight);
- SelectObject(memDC, memBM);
- */
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- dibs.dsBm.bmPlanes,
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
- NULL);
+ PSURFACE psurfBmp;
+
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ dibs.dsBm.bmBitsPixel,
+ NULL);
+ psurfBmp = SURFACE_LockSurface(Bmp);
+ ASSERT(psurfBmp);
+ /* Assign palette */
+ psurfBmp->ppal = psurf->ppal;
+ GDIOBJ_IncrementShareCount((POBJ)psurf->ppal);
+ /* Set flags */
+ psurfBmp->flags = API_BITMAP;
+ psurfBmp->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurfBmp);
}
else
{
/* A DIB section is selected in the DC */
- BITMAPINFO *bi;
+ BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
PVOID Bits;
-
- /* Allocate memory for a BITMAPINFOHEADER structure and a
- color table. The maximum number of colors in a color table
- is 256 which corresponds to a bitmap with depth 8.
- Bitmaps with higher depths don't have color tables. */
- bi = ExAllocatePoolWithTag(PagedPool,
- sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD),
- TAG_TEMP);
-
- if (bi)
+ BITMAPINFO* bi = (BITMAPINFO*)buf;
+
+ bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+ bi->bmiHeader.biWidth = Width;
+ bi->bmiHeader.biHeight = Height;
+ bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
+ bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
+ bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
+ bi->bmiHeader.biSizeImage = 0;
+ bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
+ bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
+ bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
+ bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
+
+ if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ /* Copy the color masks */
+ RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
+ }
+ else if (bi->bmiHeader.biBitCount <= 8)
{
- bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
- bi->bmiHeader.biWidth = Width;
- bi->bmiHeader.biHeight = Height;
- bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
- bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
- bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
- bi->bmiHeader.biSizeImage = 0;
- bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
- bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
- bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
- bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
-
- if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ /* Copy the color table */
+ UINT Index;
+ PPALETTE PalGDI;
+
+ if (!psurf->ppal)
{
- /* Copy the color masks */
- RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD));
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- else if (bi->bmiHeader.biBitCount <= 8)
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = 0;
+ Index < 256 && Index < PalGDI->NumColors;
+ Index++)
{
- /* Copy the color table */
- UINT Index;
- PPALGDI PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
-
- if (!PalGDI)
- {
- ExFreePoolWithTag(bi, TAG_TEMP);
- SURFACE_UnlockSurface(psurf);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- for (Index = 0;
- Index < 256 && Index < PalGDI->NumColors;
- Index++)
- {
- bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
- bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
- bi->bmiColors[Index].rgbReserved = 0;
- }
- PALETTE_UnlockPalette(PalGDI);
+ bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
+ bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+ bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ bi->bmiColors[Index].rgbReserved = 0;
}
- SURFACE_UnlockSurface(psurf);
+ PALETTE_UnlockPalette(PalGDI);
Bmp = DIB_CreateDIBSection(Dc,
bi,
NULL,
0,
0);
-
- ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp;
}
}
}
- SURFACE_UnlockSurface(psurf);
}
}
return Bmp;
}
if (!hDC)
- return IntGdiCreateBitmap(Width, Height, 1, 1, 0);
+ return GreCreateBitmap(Width, Height, 1, 1, 0);
Dc = DC_LockDc(hDC);
DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
- hDC, Width, Height, Dc->ppdev->GDIInfo.cBitsPixel);
+ hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
if (NULL == Dc)
{
_SEH2_TRY
{
ProbeForWrite(Dimension, sizeof(SIZE), 1);
- *Dimension = psurfBmp->dimension;
+ *Dimension = psurfBmp->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BOOL bInRect = FALSE;
SURFACE *psurf;
SURFOBJ *pso;
- HPALETTE Pal = 0;
- XLATEOBJ *XlateObj;
+ EXLATEOBJ exlo;
HBITMAP hBmpTmp;
dc = DC_LockDc(hDC);
if (RECTL_bPointInRect(&dc->rosdc.CombinedClip->rclBounds, XPos, YPos))
{
bInRect = TRUE;
- psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
- pso = &psurf->SurfObj;
+ psurf = dc->dclevel.pSurface;
if (psurf)
{
- Pal = psurf->hDIBPalette;
- if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault;
-
- /* FIXME: Verify if it shouldn't be PAL_BGR! */
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal);
- if (XlateObj)
+ pso = &psurf->SurfObj;
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, &gpalRGB, 0, 0xffffff, 0);
+ // check if this DC has a DIB behind it...
+ if (pso->pvScan0) // STYPE_BITMAP == pso->iType
{
- // check if this DC has a DIB behind it...
- if (pso->pvScan0) // STYPE_BITMAP == pso->iType
- {
- ASSERT(pso->lDelta);
- Result = XLATEOBJ_iXlate(XlateObj,
- DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos));
- }
- EngDeleteXlate(XlateObj);
+ ASSERT(pso->lDelta);
+ Result = XLATEOBJ_iXlate(&exlo.xlo,
+ DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos));
}
- SURFACE_UnlockSurface(psurf);
+
+ EXLATEOBJ_vCleanup(&exlo);
}
}
DC_UnlockDc(dc);
0,
0);
- //HBITMAP hBmpTmp = IntGdiCreateBitmap(1, 1, 1, 32, NULL);
+ //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL);
if (hBmpTmp)
{
HBITMAP hBmpOld = (HBITMAP)NtGdiSelectBitmap(hDCTmp, hBmpTmp);
SURFACE_UnlockSurface(psurf);
}
}
- NtGdiDeleteObject(hBmpTmp);
+ GreDeleteObject(hBmpTmp);
}
NtGdiDeleteObjectApp(hDCTmp);
}
return ret;
}
+VOID
+FASTCALL
+UnsafeGetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ OUT PBYTE pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
+
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+
+ /* Get pointers */
+ pjSrc = psurf->SurfObj.pvScan0;
+ pjDst = pvBits;
+ lDeltaSrc = psurf->SurfObj.lDelta;
+ lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+
+ while (nHeight--)
+ {
+ /* Copy one line */
+ RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
+ }
+}
+
LONG APIENTRY
NtGdiGetBitmapBits(
HBITMAP hBitmap,
OUT OPTIONAL PBYTE pUnsafeBits)
{
PSURFACE psurf;
- LONG ret;
+ LONG bmSize, ret;
if (pUnsafeBits != NULL && Bytes == 0)
{
return 0;
}
+ bmSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
+ BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
+ abs(psurf->SurfObj.sizlBitmap.cy);
+
/* If the bits vector is null, the function should return the read size */
if (pUnsafeBits == NULL)
{
- ret = psurf->SurfObj.cjBits;
SURFACE_UnlockSurface(psurf);
- return ret;
+ return bmSize;
}
/* Don't copy more bytes than the buffer has */
- Bytes = min(Bytes, psurf->SurfObj.cjBits);
+ Bytes = min(Bytes, bmSize);
// FIXME: use MmSecureVirtualMemory
_SEH2_TRY
{
ProbeForWrite(pUnsafeBits, Bytes, 1);
- ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = Bytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
-LONG APIENTRY
-IntSetBitmapBits(
- PSURFACE psurf,
- DWORD Bytes,
- IN PBYTE Bits)
-{
- LONG ret;
-
- /* Don't copy more bytes than the buffer has */
- Bytes = min(Bytes, psurf->SurfObj.cjBits);
-
-#if 0
- /* FIXME: call DDI specific function here if available */
- if (psurf->DDBitmap)
- {
- DPRINT("Calling device specific BitmapBits\n");
- if (psurf->DDBitmap->funcs->pBitmapBits)
- {
- ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap,
- (void *)Bits,
- Bytes,
- DDB_SET);
- }
- else
- {
- DPRINT("BitmapBits == NULL??\n");
- ret = 0;
- }
- }
- else
-#endif
- {
- RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- ret = Bytes;
- }
-
- return ret;
-}
-
-
LONG APIENTRY
NtGdiSetBitmapBits(
HBITMAP hBitmap,
_SEH2_TRY
{
ProbeForRead(pUnsafeBits, Bytes, 1);
- ret = IntSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = 1;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_TRY
{
ProbeForWrite(Size, sizeof(SIZE), 1);
- *Size = psurf->dimension;
+ *Size = psurf->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
/* The dimension is changed even if writing the old value failed */
- psurf->dimension.cx = Width;
- psurf->dimension.cy = Height;
+ psurf->sizlDim.cx = Width;
+ psurf->sizlDim.cy = Height;
SURFACE_UnlockSurface(psurf);
return Ret;
}
+VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
+{
+ PDC pdc = NULL;
+ RGBQUAD quad;
+ PALETTEENTRY palEntry;
+ UINT index;
+
+ switch (*Color >> 24)
+ {
+ case 0x10: /* DIBINDEX */
+ if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1)
+ {
+ *Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
+ }
+ else
+ {
+ /* Out of color table bounds - use black */
+ *Color = RGB(0, 0, 0);
+ }
+ break;
+ case 0x02: /* PALETTERGB */
+ pdc = DC_LockDc(hDC);
+ if (pdc->dclevel.hpal != NtGdiGetStockObject(DEFAULT_PALETTE))
+ {
+ index = NtGdiGetNearestPaletteIndex(pdc->dclevel.hpal, *Color);
+ IntGetPaletteEntries(pdc->dclevel.hpal, index, 1, &palEntry);
+ *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue);
+ }
+ else
+ {
+ /* Use the pure color */
+ *Color = *Color & 0x00FFFFFF;
+ }
+ DC_UnlockDc(pdc);
+ break;
+ case 0x01: /* PALETTEINDEX */
+ pdc = DC_LockDc(hDC);
+ if (IntGetPaletteEntries(pdc->dclevel.hpal, LOWORD(*Color), 1, &palEntry) == 1)
+ {
+ *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue);
+ }
+ else
+ {
+ /* Index does not exist, use zero index */
+ IntGetPaletteEntries(pdc->dclevel.hpal, 0, 1, &palEntry);
+ *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue);
+ }
+ DC_UnlockDc(pdc);
+ break;
+ default:
+ DPRINT("Unsupported color type %d passed\n", *Color >> 24);
+ break;
+ }
+}
+
BOOL APIENTRY
GdiSetPixelV(
HDC hDC,
INT Y,
COLORREF Color)
{
- HBRUSH NewBrush = NtGdiCreateSolidBrush(Color, NULL);
+ HBRUSH hBrush;
HGDIOBJ OldBrush;
- if (NewBrush == NULL)
- return(FALSE);
+ if ((Color & 0xFF000000) != 0)
+ {
+ IntHandleSpecialColorType(hDC, &Color);
+ }
+
+ hBrush = NtGdiCreateSolidBrush(Color, NULL);
+ if (hBrush == NULL)
+ return FALSE;
- OldBrush = NtGdiSelectBrush(hDC, NewBrush);
+ OldBrush = NtGdiSelectBrush(hDC, hBrush);
if (OldBrush == NULL)
{
- NtGdiDeleteObject(NewBrush);
- return(FALSE);
+ GreDeleteObject(hBrush);
+ return FALSE;
}
NtGdiPatBlt(hDC, X, Y, 1, 1, PATCOPY);
NtGdiSelectBrush(hDC, OldBrush);
- NtGdiDeleteObject(NewBrush);
+ GreDeleteObject(hBrush);
return TRUE;
}
return 0;
}
-INT FASTCALL
-BITMAP_GetWidthBytes(INT bmWidth, INT bpp)
-{
-#if 0
- switch (bpp)
- {
- case 1:
- return 2 * ((bmWidth+15) >> 4);
-
- case 24:
- bmWidth *= 3; /* fall through */
- case 8:
- return bmWidth + (bmWidth & 1);
-
- case 32:
- return bmWidth * 4;
-
- case 16:
- case 15:
- return bmWidth * 2;
-
- case 4:
- return 2 * ((bmWidth+3) >> 2);
-
- default:
- DPRINT ("stub");
- }
-
- return -1;
-#endif
-
- return ((bmWidth * bpp + 15) & ~15) >> 3;
-}
-
HBITMAP FASTCALL
BITMAP_CopyBitmap(HBITMAP hBitmap)
{
return 0;
}
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
+ Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
Size.cx = abs(bm.bmWidth);
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bm.bmBitsPixel * bm.bmPlanes, BI_RGB),
- (bm.bmHeight < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT,
- NULL);
+ res = GreCreateBitmapEx(Size.cx,
+ Size.cy,
+ bm.bmWidthBytes,
+ Bitmap->SurfObj.iBitmapFormat,
+ Bitmap->SurfObj.fjBitmap,
+ Bitmap->SurfObj.cjBits,
+ NULL,
+ Bitmap->flags);
+
if (res)
{
- PBYTE buf;
-
- resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP);
+ resBitmap = SURFACE_LockSurface(res);
if (resBitmap)
{
- buf = ExAllocatePoolWithTag(PagedPool,
- bm.bmWidthBytes * abs(bm.bmHeight),
- TAG_BITMAP);
- if (buf == NULL)
- {
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
- NtGdiDeleteObject(res);
- return 0;
- }
- IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- ExFreePoolWithTag(buf,TAG_BITMAP);
- resBitmap->flFlags = Bitmap->flFlags;
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
+ IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
+ SURFACE_UnlockSurface(resBitmap);
}
else
{
- NtGdiDeleteObject(res);
+ GreDeleteObject(res);
res = NULL;
}
}
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
+ SURFACE_UnlockSurface(Bitmap);
return res;
}
pBitmap->bmType = 0;
pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
- pBitmap->bmWidthBytes = abs(psurf->SurfObj.lDelta);
pBitmap->bmPlanes = 1;
pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
/* Check for DIB section */
if (psurf->hSecure)
{
/* Set bmBits in this case */
pBitmap->bmBits = psurf->SurfObj.pvBits;
+ /* DIBs data are 32 bits aligned */
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
if (Count >= sizeof(DIBSECTION))
{
pds->dsBmih.biHeight = pds->dsBm.bmHeight;
pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
- pds->dsBmih.biCompression = 0; // FIXME!
+ if(psurf->ppal->flFlags & PAL_BITFIELDS)
+ {
+ pds->dsBmih.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ switch (psurf->SurfObj.iBitmapFormat)
+ {
+ case BMF_1BPP:
+ case BMF_4BPP:
+ case BMF_8BPP:
+ case BMF_16BPP:
+ case BMF_24BPP:
+ case BMF_32BPP:
+ pds->dsBmih.biCompression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ pds->dsBmih.biCompression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ pds->dsBmih.biCompression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ pds->dsBmih.biCompression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ pds->dsBmih.biCompression = BI_PNG;
+ break;
+ }
+ }
pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
pds->dsBmih.biXPelsPerMeter = 0;
pds->dsBmih.biYPelsPerMeter = 0;
- pds->dsBmih.biClrUsed = psurf->biClrUsed;
+ pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
pds->dsBmih.biClrImportant = psurf->biClrImportant;
- pds->dsBitfields[0] = psurf->dsBitfields[0];
- pds->dsBitfields[1] = psurf->dsBitfields[1];
- pds->dsBitfields[2] = psurf->dsBitfields[2];
+ pds->dsBitfields[0] = psurf->ppal->RedMask;
+ pds->dsBitfields[1] = psurf->ppal->GreenMask;
+ pds->dsBitfields[2] = psurf->ppal->BlueMask;
pds->dshSection = psurf->hDIBSection;
pds->dsOffset = psurf->dwOffset;
NtGdiGetDCforBitmap(
IN HBITMAP hsurf)
{
- HDC hDC = NULL;
+ HDC hdc = NULL;
PSURFACE psurf = SURFACE_LockSurface(hsurf);
if (psurf)
{
- hDC = psurf->hDC;
+ hdc = psurf->hdc;
SURFACE_UnlockSurface(psurf);
}
- return hDC;
+ return hdc;
}
-/*
- * @implemented
- */
-HBITMAP
-APIENTRY
-NtGdiSelectBitmap(
- IN HDC hDC,
- IN HBITMAP hBmp)
-{
- PDC pDC;
- PDC_ATTR pdcattr;
- HBITMAP hOrgBmp;
- PSURFACE psurfBmp;
- HRGN hVisRgn;
- BOOLEAN bFailed;
- PGDIBRUSHOBJ pBrush;
-
- if (hDC == NULL || hBmp == NULL) return NULL;
-
- pDC = DC_LockDc(hDC);
- if (!pDC)
- {
- return NULL;
- }
-
- pdcattr = pDC->pdcattr;
-
- /* must be memory dc to select bitmap */
- if (pDC->dctype != DC_TYPE_MEMORY)
- {
- DC_UnlockDc(pDC);
- return NULL;
- }
-
- psurfBmp = SURFACE_LockSurface(hBmp);
- if (!psurfBmp)
- {
- DC_UnlockDc(pDC);
- return NULL;
- }
- hOrgBmp = pDC->rosdc.hBitmap;
-
- /* Release the old bitmap, lock the new one and convert it to a SURF */
- pDC->rosdc.hBitmap = hBmp;
-
- // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
- pDC->dclevel.pSurface = psurfBmp;
- psurfBmp->hDC = hDC;
-
- // if we're working with a DIB, get the palette
- // [fixme: only create if the selected palette is null]
- if (psurfBmp->hSecure)
- {
-// pDC->rosdcbitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
- pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
- }
- else
- {
- pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
- }
-
- hVisRgn = NtGdiCreateRectRgn(0,
- 0,
- psurfBmp->SurfObj.sizlBitmap.cx,
- psurfBmp->SurfObj.sizlBitmap.cy);
- SURFACE_UnlockSurface(psurfBmp);
-
- /* Regenerate the XLATEOBJs. */
- pBrush = BRUSHOBJ_LockBrush(pdcattr->hbrush);
- if (pBrush)
- {
- if (pDC->rosdc.XlateBrush)
- {
- EngDeleteXlate(pDC->rosdc.XlateBrush);
- }
- pDC->rosdc.XlateBrush = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
- BRUSHOBJ_UnlockBrush(pBrush);
- }
-
- pBrush = PENOBJ_LockPen(pdcattr->hpen);
- if (pBrush)
- {
- if (pDC->rosdc.XlatePen)
- {
- EngDeleteXlate(pDC->rosdc.XlatePen);
- }
- pDC->rosdc.XlatePen = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
- PENOBJ_UnlockPen(pBrush);
- }
-
- DC_UnlockDc(pDC);
-
- if (hVisRgn)
- {
- GdiSelectVisRgn(hDC, hVisRgn);
- NtGdiDeleteObject(hVisRgn);
- }
-
- return hOrgBmp;
-}
/* EOF */