1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: win32ss/gdi/gdi32/objects/metafile.c 5 * PURPOSE: metafile and enhanced metafile support 6 * PROGRAMMERS: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 7 */ 8 #include <precomp.h> 9 10 #define NDEBUG 11 #include <debug.h> 12 13 /* FUNCTIONS *****************************************************************/ 14 15 /* 16 * @implemented 17 */ 18 BOOL 19 WINAPI 20 GdiIsPlayMetafileDC(HDC hDC) 21 { 22 #if 0 23 PLDC pLDC = GdiGetLDC(hDC); 24 if ( pLDC ) 25 { 26 if ( pLDC->Flags & LDC_PLAY_MFDC ) return TRUE; 27 } 28 return FALSE; 29 #else 30 UNIMPLEMENTED; 31 return FALSE; 32 #endif 33 } 34 35 /* 36 * @implemented 37 */ 38 BOOL 39 WINAPI 40 GdiIsMetaFileDC(HDC hdc) 41 { 42 ULONG ulObjType; 43 44 ulObjType = GDI_HANDLE_GET_TYPE(hdc); 45 if (ulObjType == GDILoObjType_LO_METADC16_TYPE) 46 { 47 return TRUE; 48 } 49 50 if (ulObjType == GDILoObjType_LO_ALTDC_TYPE) 51 { 52 #if 0 53 PLDC pLDC = GdiGetLDC(hdc); 54 if ( !pLDC ) 55 { 56 SetLastError(ERROR_INVALID_HANDLE); 57 return FALSE; 58 } 59 if ( pLDC->iType == LDC_EMFLDC) return TRUE; 60 return FALSE; 61 #endif 62 return TRUE; 63 } 64 65 return FALSE; 66 } 67 68 /* 69 * @implemented 70 */ 71 BOOL 72 WINAPI 73 GdiIsMetaPrintDC(HDC hDC) 74 { 75 #if 0 76 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) 77 { 78 if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) 79 return FALSE; 80 else 81 { 82 PLDC pLDC = GdiGetLDC(hDC); 83 if ( !pLDC ) 84 { 85 SetLastError(ERROR_INVALID_HANDLE); 86 return FALSE; 87 } 88 if ( pLDC->Flags & LDC_META_PRINT) return TRUE; 89 } 90 } 91 return FALSE; 92 #else 93 UNIMPLEMENTED; 94 return FALSE; 95 #endif 96 } 97 98 // NOTE: I wanna use GdiCreateLocalMetaFilePict and GdiConvertMetaFilePict 99 // functions for clipboard data conversion. --- katahiromz 100 101 /* 102 * @implemented 103 */ 104 HGLOBAL 105 WINAPI 106 GdiCreateLocalMetaFilePict(HANDLE hmo) 107 { 108 HGLOBAL hMetaFilePict; 109 METAFILEPICT * pInfo; 110 HMETAFILE hMF = NULL; 111 BYTE * Buffer = NULL; 112 BYTE * BufNew = NULL; 113 HDC hDC = NULL; 114 UINT nSize, cSize; 115 DWORD iType; 116 117 // NOTE: On Win32, there is no difference between the local heap and 118 // the global heap. GlobalAlloc and LocalAlloc have same effect. 119 120 // allocate for METAFILEPICT 121 hMetaFilePict = GlobalAlloc(GHND | GMEM_SHARE, sizeof(METAFILEPICT)); 122 pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict); 123 if (pInfo == NULL) 124 goto Exit; 125 126 nSize = NtGdiGetServerMetaFileBits( hmo, 0, NULL, NULL, NULL, NULL, NULL ); 127 128 // allocate buffer 129 Buffer = (BYTE *)LocalAlloc(LPTR, nSize); 130 if (Buffer == NULL) 131 goto Exit; 132 133 // store to buffer 134 nSize = NtGdiGetServerMetaFileBits( hmo, nSize, Buffer, &iType, (PDWORD)&pInfo->mm, (PDWORD)&pInfo->xExt, (PDWORD)&pInfo->yExt ); 135 if (nSize == 0) 136 goto Exit; 137 138 if ( iType == GDITAG_TYPE_EMF ) // handle conversion to MFP 139 { 140 static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' }; 141 HENHMETAFILE hEMF; 142 ENHMETAHEADER emh; 143 144 hEMF = SetEnhMetaFileBits(nSize, Buffer); 145 if (hEMF == NULL) 146 goto Exit; 147 148 if (!GetEnhMetaFileHeader( hEMF, sizeof(emh), &emh )) 149 { 150 DeleteEnhMetaFile(hEMF); 151 goto Exit; 152 } 153 154 pInfo->mm = MM_ANISOTROPIC; // wine uses MM_ISOTROPIC. 155 pInfo->xExt = emh.rclFrame.right - emh.rclFrame.left; // Width 156 pInfo->yExt = emh.rclFrame.bottom - emh.rclFrame.top; // Height 157 158 hDC = CreateDCW(szDisplayW, NULL, NULL, NULL); 159 if (hDC) 160 { 161 cSize = GetWinMetaFileBits( hEMF, 0, NULL, MM_ANISOTROPIC, hDC ); 162 if (cSize) 163 { 164 BufNew = (BYTE *)LocalAlloc(LPTR, cSize); 165 if (BufNew) 166 { 167 nSize = GetWinMetaFileBits( hEMF, cSize, (LPBYTE)BufNew, MM_ANISOTROPIC, hDC ); 168 if (nSize == cSize) 169 { 170 if (Buffer) LocalFree(Buffer); 171 Buffer = BufNew; 172 } 173 } 174 } 175 DeleteDC(hDC); 176 } 177 DeleteEnhMetaFile(hEMF); 178 179 if (Buffer != BufNew) 180 goto Exit; 181 } 182 183 // create metafile from buffer 184 hMF = SetMetaFileBitsEx(nSize, Buffer); 185 if (hMF == NULL) 186 goto Exit; 187 188 // set metafile handle 189 pInfo->hMF = hMF; 190 191 Exit: 192 // clean up 193 if (Buffer) 194 LocalFree(Buffer); 195 if (pInfo) 196 GlobalUnlock(hMetaFilePict); 197 if (hMF == NULL) 198 { 199 // failure 200 GlobalFree(hMetaFilePict); 201 hMetaFilePict = NULL; 202 } 203 204 return hMetaFilePict; // success if non-NULL 205 } 206 207 /* 208 * @implemented 209 */ 210 HANDLE 211 WINAPI 212 GdiConvertMetaFilePict(HGLOBAL hMetaFilePict) 213 { 214 HMETAFILE hMF; 215 UINT nSize; 216 HANDLE hmo = NULL; 217 BYTE * Buffer = NULL; 218 METAFILEPICT * pInfo = NULL; 219 220 // get METAFILEPICT pointer 221 pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict); 222 if (pInfo == NULL) 223 goto Exit; 224 225 // get metafile handle 226 hMF = pInfo->hMF; 227 228 // get size of buffer 229 nSize = GetMetaFileBitsEx(hMF, 0, NULL); 230 if (nSize == 0) 231 goto Exit; 232 233 // allocate buffer 234 Buffer = (BYTE *)LocalAlloc(LPTR, nSize); 235 if (Buffer == NULL) 236 goto Exit; 237 238 // store to buffer 239 nSize = GetMetaFileBitsEx(hMF, nSize, Buffer); 240 if (nSize == 0) 241 goto Exit; 242 243 hmo = NtGdiCreateServerMetaFile( GDITAG_TYPE_MFP, nSize, Buffer, pInfo->mm, pInfo->xExt, pInfo->yExt); 244 245 Exit: 246 // clean up 247 if (pInfo) 248 GlobalUnlock(hMetaFilePict); 249 if (Buffer) 250 LocalFree(Buffer); 251 return hmo; // success if non-NULL 252 } 253