Implemented StretchDIBits in the EMF code.
[wine/dcerpc.git] / dlls / gdi / enhmfdrv / bitblt.c
blob92910ffd5aee4a49dd78a6030bfa8a3ad8864ff6
1 /*
2 * Enhanced MetaFile driver BitBlt functions
4 * Copyright 2002 Huw D M Davies for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <string.h>
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "gdi.h"
26 #include "enhmetafiledrv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);
31 BOOL EMFDRV_PatBlt( PHYSDEV dev, INT left, INT top,
32 INT width, INT height, DWORD rop )
34 EMRBITBLT emr;
35 BOOL ret;
37 emr.emr.iType = EMR_BITBLT;
38 emr.emr.nSize = sizeof(emr);
39 emr.rclBounds.left = left;
40 emr.rclBounds.top = top;
41 emr.rclBounds.right = left + width - 1;
42 emr.rclBounds.bottom = top + height - 1;
43 emr.xDest = left;
44 emr.yDest = top;
45 emr.cxDest = width;
46 emr.cyDest = height;
47 emr.dwRop = rop;
48 emr.xSrc = 0;
49 emr.ySrc = 0;
50 emr.xformSrc.eM11 = 1.0;
51 emr.xformSrc.eM12 = 0.0;
52 emr.xformSrc.eM21 = 0.0;
53 emr.xformSrc.eM22 = 1.0;
54 emr.xformSrc.eDx = 0.0;
55 emr.xformSrc.eDy = 0.0;
56 emr.crBkColorSrc = 0;
57 emr.iUsageSrc = 0;
58 emr.offBmiSrc = 0;
59 emr.cbBmiSrc = 0;
60 emr.offBitsSrc = 0;
61 emr.cbBitsSrc = 0;
63 ret = EMFDRV_WriteRecord( dev, &emr.emr );
64 if(ret)
65 EMFDRV_UpdateBBox( dev, &emr.rclBounds );
66 return ret;
70 INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
71 INT heightDst, INT xSrc, INT ySrc,
72 INT widthSrc, INT heightSrc,
73 const void *bits, const BITMAPINFO *info,
74 UINT wUsage, DWORD dwRop )
76 EMRSTRETCHDIBITS *emr;
77 BOOL ret;
78 UINT bmi_size=0, bits_size, emr_size;
79 UINT width_bytes;
81 /* calculate the size of the bits we need to store */
82 switch(info->bmiHeader.biBitCount)
84 case 1:
85 width_bytes = (info->bmiHeader.biWidth+7)/8;
86 break;
87 case 4:
88 width_bytes = (info->bmiHeader.biWidth+1)/2;
89 break;
90 case 8:
91 width_bytes = info->bmiHeader.biWidth;
92 break;
93 case 16:
94 width_bytes = info->bmiHeader.biWidth*2;
95 break;
96 case 24:
97 width_bytes = info->bmiHeader.biWidth*3;
98 break;
99 case 32:
100 width_bytes = info->bmiHeader.biWidth*4;
101 break;
102 default:
103 FIXME("bi.biCount has and unknown value (%d)\n", info->bmiHeader.biBitCount);
104 return FALSE;
106 width_bytes = ((width_bytes+3)/4) << 2;
107 bits_size = width_bytes * info->bmiHeader.biHeight;
109 /* calculate the size of the colour table */
110 bmi_size = sizeof (BITMAPINFO);
111 if ( info->bmiHeader.biBitCount <= 8 )
113 UINT num_colors = info->bmiHeader.biClrUsed;
114 if ( num_colors == 0 )
115 num_colors = (1<<info->bmiHeader.biBitCount);
116 bmi_size += num_colors*sizeof(RGBQUAD);
119 emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + bits_size;
120 emr = HeapAlloc(GetProcessHeap(), 0, emr_size );
122 /* write a bitmap info header (with colours) to the record */
123 memcpy( &emr[1], info, bmi_size);
125 /* write bitmap bits to the record */
126 memcpy ( ( (BYTE *) (&emr[1]) ) + bmi_size, bits, bits_size);
128 /* fill in the EMR header at the front of our piece of memory */
129 emr->emr.iType = EMR_STRETCHDIBITS;
130 emr->emr.nSize = emr_size;
132 emr->xDest = xDst;
133 emr->yDest = yDst;
134 emr->cxDest = widthDst;
135 emr->cyDest = heightDst;
136 emr->dwRop = dwRop;
137 emr->xSrc = xSrc; /* FIXME: only save the piece of the bitmap needed */
138 emr->ySrc = ySrc;
140 emr->iUsageSrc = DIB_RGB_COLORS;
141 emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS);
142 emr->cbBmiSrc = bmi_size;
143 emr->offBitsSrc = emr->offBmiSrc + bmi_size;
144 emr->cbBitsSrc = bits_size;
146 emr->cxSrc = widthSrc;
147 emr->cySrc = heightSrc;
149 emr->rclBounds.left = xDst;
150 emr->rclBounds.top = yDst;
151 emr->rclBounds.right = xDst + widthDst;
152 emr->rclBounds.bottom = yDst + heightDst;
154 /* save the record we just created */
155 ret = EMFDRV_WriteRecord( dev, &emr->emr );
156 if(ret)
157 EMFDRV_UpdateBBox( dev, &emr->rclBounds );
159 HeapFree(GetProcessHeap(), 0, emr);
161 return ret;