Commit 56166a6f authored by Huw D M Davies's avatar Huw D M Davies Committed by Alexandre Julliard

Implemented recording of StretchDIBits and SetDIBitsToDevice and

playback of SetDIBitsToDevice. Cleaned up PlayMetaFileRecord a bit.
parent 94bb5bb1
......@@ -8,6 +8,7 @@
#include "metafiledrv.h"
#include "heap.h"
#include "debug.h"
#include "bitmap.h"
DEFAULT_DEBUG_CHANNEL(metafile)
......@@ -150,3 +151,84 @@ BOOL MFDRV_StretchBlt( DC *dcDst, INT xDst, INT yDst, INT widthDst,
}
/***********************************************************************
* MFDRV_StretchDIBits
*/
INT MFDRV_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 len, infosize, imagesize;
METARECORD *mr;
infosize = DIB_BitmapInfoSize(info, wUsage);
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
mr = (METARECORD *)HeapAlloc( SystemHeap, 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_STRETCHDIB;
mr->rdParm[0] = LOWORD(dwRop);
mr->rdParm[1] = HIWORD(dwRop);
mr->rdParm[2] = wUsage;
mr->rdParm[3] = (INT16)heightSrc;
mr->rdParm[4] = (INT16)widthSrc;
mr->rdParm[5] = (INT16)ySrc;
mr->rdParm[6] = (INT16)xSrc;
mr->rdParm[7] = (INT16)heightDst;
mr->rdParm[8] = (INT16)widthDst;
mr->rdParm[9] = (INT16)yDst;
mr->rdParm[10] = (INT16)xDst;
memcpy(mr->rdParm + 11, info, infosize);
memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize);
MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
HeapFree( SystemHeap, 0, mr );
return heightSrc;
}
/***********************************************************************
* MFDRV_SetDIBitsToDeivce
*/
INT MFDRV_SetDIBitsToDevice( DC *dc, INT xDst, INT yDst, DWORD cx,
DWORD cy, INT xSrc, INT ySrc, UINT startscan,
UINT lines, LPCVOID bits, const BITMAPINFO *info,
UINT coloruse )
{
DWORD len, infosize, imagesize;
METARECORD *mr;
infosize = DIB_BitmapInfoSize(info, coloruse);
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
mr = (METARECORD *)HeapAlloc( SystemHeap, 0, len );
if(!mr) return 0;
mr->rdSize = len / 2;
mr->rdFunction = META_SETDIBTODEV;
mr->rdParm[0] = coloruse;
mr->rdParm[1] = lines;
mr->rdParm[2] = startscan;
mr->rdParm[3] = (INT16)ySrc;
mr->rdParm[4] = (INT16)xSrc;
mr->rdParm[5] = (INT16)cy;
mr->rdParm[6] = (INT16)cx;
mr->rdParm[7] = (INT16)yDst;
mr->rdParm[8] = (INT16)xDst;
memcpy(mr->rdParm + 9, info, infosize);
memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize);
MFDRV_WriteRecord( dc, mr, mr->rdSize * 2 );
HeapFree( SystemHeap, 0, mr );
return lines;
}
......@@ -69,7 +69,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
MFDRV_SetBkColor, /* pSetBkColor */
NULL, /* pSetBkMode */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDIBitsToDevice */
MFDRV_SetDIBitsToDevice, /* pSetDIBitsToDevice */
MFDRV_SetMapMode, /* pSetMapMode */
NULL, /* pSetMapperFlags */
MFDRV_SetPixel, /* pSetPixel */
......@@ -86,7 +86,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
MFDRV_SetWindowExt, /* pSetWindowExt */
MFDRV_SetWindowOrg, /* pSetWindowOrg */
MFDRV_StretchBlt, /* pStretchBlt */
NULL /* pStretchDIBits */
MFDRV_StretchDIBits /* pStretchDIBits */
};
......
......@@ -56,7 +56,7 @@ extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap );
/* objects/dib.c */
extern int DIB_GetDIBWidthBytes( int width, int depth );
extern int DIB_GetDIBImageBytes( int width, int height, int depth );
extern int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse );
extern int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse );
extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
int *height, WORD *bpp, WORD *compr );
extern void DIB_UpdateDIBSection( DC *dc, BOOL toDIB );
......
......@@ -86,5 +86,14 @@ extern BOOL MFDRV_ExtTextOut( struct tagDC *dc, INT x, INT y,
UINT flags, const RECT *lprect, LPCSTR str,
UINT count, const INT *lpDx );
extern BOOL MFDRV_PaintRgn( DC *dc, HRGN hrgn );
extern INT MFDRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
DWORD cy, INT xSrc, INT ySrc,
UINT startscan, UINT lines, LPCVOID bits,
const BITMAPINFO *info, UINT coloruse );
extern INT MFDRV_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 );
#endif /* __WINE_METAFILEDRV_H */
......@@ -58,7 +58,7 @@ int DIB_GetDIBImageBytes( int width, int height, int depth )
*
* Return the size of the bitmap info structure including color table.
*/
int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
{
int colors;
......
......@@ -696,6 +696,8 @@ BOOL WINAPI EnumMetaFile(
while (offset < (mh->mtSize * 2))
{
mr = (METARECORD *)((char *)mh + offset);
TRACE(metafile, "Calling EnumFunc with record type %x\n",
mr->rdFunction);
if (!lpEnumFunc( hdc, ht, mr, mh->mtNoObjects, (LONG)lpData ))
{
result = FALSE;
......@@ -724,7 +726,7 @@ BOOL WINAPI EnumMetaFile(
}
static BOOL MF_Play_MetaCreateRegion( METARECORD *mr, HRGN hrgn );
static BOOL MF_Play_MetaExtTextOut(HDC16 hdc, METARECORD *mr);
/******************************************************************
* PlayMetaFileRecord16 (GDI.176)
*
......@@ -735,7 +737,7 @@ static BOOL MF_Play_MetaCreateRegion( METARECORD *mr, HRGN hrgn );
* BUGS
* The following metafile records are unimplemented:
*
* FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
* FRAMEREGION, DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
* RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
* ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
*
......@@ -932,7 +934,7 @@ void WINAPI PlayMetaFileRecord16(
case META_CHORD:
Chord(hdc, (INT16)*(mr->rdParm + 7), (INT16)*(mr->rdParm + 6),
(INT16)*(mr->rdParm+5), (INT16)*(mr->rdParm + 4),
(INT16)*(mr->rdParm + 5), (INT16)*(mr->rdParm + 4),
(INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
(INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
break;
......@@ -960,6 +962,12 @@ void WINAPI PlayMetaFileRecord16(
MF_AddHandle(ht, nHandles,
CreateDIBPatternBrush(hndl, *(mr->rdParm + 1)));
GlobalFree16(hndl);
break;
default:
ERR(metafile, "META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
mr->rdParm[0]);
break;
}
break;
......@@ -1005,43 +1013,7 @@ void WINAPI PlayMetaFileRecord16(
break;
case META_EXTTEXTOUT:
{
LPINT16 dxx;
LPSTR sot;
DWORD len;
s1 = mr->rdParm[2]; /* String length */
len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
+ sizeof(UINT16) + (mr->rdParm[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
sot= (LPSTR)&mr->rdParm[4]; /* start_of_text */
if (mr->rdParm[3])
sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
if (mr->rdSize == len / 2)
dxx = NULL; /* determine if array present */
else
if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
else
{
TRACE(metafile,"%s len: %ld\n",
sot,mr->rdSize);
WARN(metafile,
"Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
len,s1,mr->rdSize,mr->rdParm[3]);
dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
}
ExtTextOut16( hdc, mr->rdParm[1], /* X position */
mr->rdParm[0], /* Y position */
mr->rdParm[3], /* options */
mr->rdParm[3] ? (LPRECT16) &mr->rdParm[4]:NULL, /* rectangle */
sot, /* string */
s1, dxx); /* length, dx array */
if (dxx)
TRACE(metafile,"%s len: %ld dx0: %d\n",
sot,mr->rdSize,dxx[0]);
}
MF_Play_MetaExtTextOut( hdc, mr );
break;
case META_STRETCHDIB:
......@@ -1128,43 +1100,42 @@ void WINAPI PlayMetaFileRecord16(
break;
case META_DIBCREATEPATTERNBRUSH:
/* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
/* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN:
but there's no difference */
TRACE(metafile,"%d\n",*(mr->rdParm));
s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
ptr = GlobalLock16(hndl);
memcpy(ptr, mr->rdParm + 2, s1);
GlobalUnlock16(hndl);
MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParm + 1)));
MF_AddHandle(ht, nHandles,
CreateDIBPatternBrush16(hndl, *(mr->rdParm + 1)));
GlobalFree16(hndl);
break;
case META_DIBBITBLT:
{
/*In practice ive found that theres two layout for META_DIBBITBLT,
one (the first here) is the usual one when a src dc is actually passed
int, the second occurs when the src dc is passed in as NULL to
the creating BitBlt.
as the second case has no dib, a size check will suffice to distinguish.
/* In practice I've found that there are two layouts for
META_DIBBITBLT, one (the first here) is the usual one when a src
dc is actually passed to it, the second occurs when the src dc is
passed in as NULL to the creating BitBlt. As the second case has
no dib, a size check will suffice to distinguish.
Caolan.McNamara@ul.ie */
Caolan.McNamara@ul.ie
*/
if (mr->rdSize > 12)
{
if (mr->rdSize > 12) {
LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[8]);
LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[0] );
StretchDIBits16(hdc,mr->rdParm[7],mr->rdParm[6],mr->rdParm[5],
mr->rdParm[4],mr->rdParm[3],mr->rdParm[2],
mr->rdParm[5],mr->rdParm[4],bits,info,
DIB_RGB_COLORS,MAKELONG(mr->rdParm[0],mr->rdParm[1]));
}
else /*equivalent to a PatBlt*/
{
LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize(info, mr->rdParm[0]);
StretchDIBits16(hdc, mr->rdParm[7], mr->rdParm[6], mr->rdParm[5],
mr->rdParm[4], mr->rdParm[3], mr->rdParm[2],
mr->rdParm[5], mr->rdParm[4], bits, info,
DIB_RGB_COLORS,
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
} else { /* equivalent to a PatBlt */
PatBlt16(hdc, mr->rdParm[8], mr->rdParm[7],
mr->rdParm[6], mr->rdParm[5],
MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
}
MAKELONG(mr->rdParm[0], mr->rdParm[1]));
}
break;
......@@ -1178,13 +1149,27 @@ void WINAPI PlayMetaFileRecord16(
case META_EXTFLOODFILL:
ExtFloodFill(hdc, (INT16)*(mr->rdParm + 4), (INT16)*(mr->rdParm + 3),
MAKELONG(*(mr->rdParm+1), *(mr->rdParm + 2)),*(mr->rdParm));
MAKELONG(*(mr->rdParm+1), *(mr->rdParm + 2)),
*(mr->rdParm));
break;
#define META_UNIMP(x) case x: FIXME(metafile, "PlayMetaFileRecord:record type "#x" not implemented.\n");break;
case META_SETDIBTODEV:
{
BITMAPINFO *info = (BITMAPINFO *) &(mr->rdParm[9]);
char *bits = (char *)info + DIB_BitmapInfoSize( info, mr->rdParm[0] );
SetDIBitsToDevice(hdc, (INT16)mr->rdParm[8], (INT16)mr->rdParm[7],
(INT16)mr->rdParm[6], (INT16)mr->rdParm[5],
(INT16)mr->rdParm[4], (INT16)mr->rdParm[3],
mr->rdParm[2], mr->rdParm[1], bits, info,
mr->rdParm[0]);
break;
}
#define META_UNIMP(x) case x: \
FIXME(metafile, "PlayMetaFileRecord:record type "#x" not implemented.\n"); \
break;
META_UNIMP(META_FRAMEREGION)
META_UNIMP(META_DRAWTEXT)
META_UNIMP(META_SETDIBTODEV)
META_UNIMP(META_ANIMATEPALETTE)
META_UNIMP(META_SETPALENTRIES)
META_UNIMP(META_RESIZEPALETTE)
......@@ -1409,5 +1394,48 @@ static BOOL MF_Play_MetaCreateRegion( METARECORD *mr, HRGN hrgn )
}
/* LocalWords: capatibility
/******************************************************************
* MF_Play_MetaExtTextOut
*
* Handles META_EXTTEXTOUT for PlayMetaFileRecord().
*/
static BOOL MF_Play_MetaExtTextOut(HDC16 hdc, METARECORD *mr)
{
LPINT16 dxx;
LPSTR sot;
DWORD len;
WORD s1;
s1 = mr->rdParm[2]; /* String length */
len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
+ sizeof(UINT16) + (mr->rdParm[3] ? sizeof(RECT16) : 0);
/* rec len without dx array */
sot = (LPSTR)&mr->rdParm[4]; /* start_of_text */
if (mr->rdParm[3])
sot += sizeof(RECT16); /* there is a rectangle, so add offset */
if (mr->rdSize == len / 2)
dxx = NULL; /* determine if array present */
else
if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
else {
TRACE(metafile,"%s len: %ld\n", sot, mr->rdSize);
WARN(metafile,
"Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
len, s1, mr->rdSize, mr->rdParm[3]);
dxx = NULL; /* should't happen -- but if, we continue with NULL */
}
ExtTextOut16( hdc, mr->rdParm[1], /* X position */
mr->rdParm[0], /* Y position */
mr->rdParm[3], /* options */
mr->rdParm[3] ? (LPRECT16) &mr->rdParm[4]:NULL,
/* rectangle */
sot, /* string */
s1, dxx); /* length, dx array */
if (dxx)
TRACE(metafile,"%s len: %ld dx0: %d\n", sot, mr->rdSize, dxx[0]);
return TRUE;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment