/* DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET */ TW_UINT16 GPHOTO2_ImageNativeXferGet (pTW_IDENTITY pOrigin, TW_MEMREF pData) { #ifdef HAVE_GPHOTO2 pTW_UINT32 pHandle = (pTW_UINT32) pData; HBITMAP hDIB; BITMAPINFO bmpInfo; LPBYTE bits, oldbits; JSAMPROW samprow, oldsamprow; HDC dc; FIXME("DG_IMAGE/DAT_IMAGENATIVEXFER/MSG_GET: implemented, but expect program crash due to DIB.\n"); /* NOTE NOTE NOTE NOTE NOTE NOTE NOTE * * While this is a mandatory transfer mode and this function * is correctly implemented and fully works, the calling program * will likely crash after calling. * * Reason is that there is a lot of example code that does: * bmpinfo = (LPBITMAPINFOHEADER)GlobalLock(hBITMAP); ... pointer access to bmpinfo * * Our current HBITMAP handles do not support getting GlobalLocked -> App Crash * * This needs a GDI Handle rewrite, at least for DIB sections. * - Marcus */ if (activeDS.currentState != 6) { activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } if (TWRC_SUCCESS != _get_image_and_startup_jpeg()) { FIXME("Failed to get an image\n"); activeDS.twCC = TWCC_OPERATIONERROR; return TWRC_FAILURE; } TRACE("Acquiring image %dx%dx%d bits from gphoto.\n", activeDS.jd.output_width, activeDS.jd.output_height, activeDS.jd.output_components*8); ZeroMemory (&bmpInfo, sizeof (BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = activeDS.jd.output_width; bmpInfo.bmiHeader.biHeight = -activeDS.jd.output_height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = activeDS.jd.output_components*8; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; hDIB = CreateDIBSection ((dc = GetDC(activeDS.hwndOwner)), &bmpInfo, DIB_RGB_COLORS, (LPVOID)&bits, 0, 0); if (!hDIB) { FIXME("Failed creating DIB.\n"); gp_file_unref (activeDS.file); activeDS.file = NULL; activeDS.twCC = TWCC_LOWMEMORY; return TWRC_FAILURE; } samprow = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,activeDS.jd.output_width*activeDS.jd.output_components); oldbits = bits; oldsamprow = samprow; while ( activeDS.jd.output_scanline<activeDS.jd.output_height ) { int i, x = pjpeg_read_scanlines(&activeDS.jd,&samprow,1); if (x != 1) { FIXME("failed to read current scanline?\n"); break; } /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */ for(i=0;i<activeDS.jd.output_width;i++,samprow+=activeDS.jd.output_components) { *(bits++) = *(samprow+2); *(bits++) = *(samprow+1); *(bits++) = *(samprow); } bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3); samprow = oldsamprow; } bits = oldbits; HeapFree (GetProcessHeap(), 0, samprow); gp_file_unref (activeDS.file); activeDS.file = NULL; ReleaseDC (activeDS.hwndOwner, dc); *pHandle = (TW_UINT32)hDIB; activeDS.twCC = TWCC_SUCCESS; activeDS.currentState = 7; return TWRC_XFERDONE; #else return TWRC_FAILURE; #endif }
//----------------------------------------------------------------------------- // Name: InitDeviceObjects() // Desc: Initializes device-dependent objects, including the vertex buffer used // for rendering text and the texture map which stores the font image. //----------------------------------------------------------------------------- HRESULT CD3DFont::InitDeviceObjects( LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ) { HRESULT hr; // Keep a local copy of the device m_pd3dDevice = pd3dDevice; typedef enum FontFormats { eNull, eX4R4G4B4, eR5G6B5, eX8R8G8B8, }FontFormats; FontFormats fmt = eNull; // Establish the font and texture size m_fTextScale = 1.0f; // Draw fonts into texture without scaling // Large fonts need larger textures if( m_dwFontHeight > 40 ) m_dwTexWidth = m_dwTexHeight = 1024; else if( m_dwFontHeight > 20 ) m_dwTexWidth = m_dwTexHeight = 512; else m_dwTexWidth = m_dwTexHeight = 256; // If requested texture is too big, use a smaller texture and smaller font, // and scale up when rendering. D3DDEVICEDESC7 d3dCaps; m_pd3dDevice->GetCaps( &d3dCaps ); if( m_dwTexWidth > d3dCaps.dwMaxTextureWidth ) { m_fTextScale = (FLOAT)d3dCaps.dwMaxTextureWidth / (FLOAT)m_dwTexWidth; m_dwTexWidth = m_dwTexHeight = d3dCaps.dwMaxTextureWidth; } DDSURFACEDESC2 ddsd; INITDDSTRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTSTATIC; ddsd.dwWidth = m_dwTexWidth; ddsd.dwHeight = m_dwTexHeight; IDirectDrawSurface7 * pRT = NULL; hr = m_pd3dDevice->GetRenderTarget( &pRT ); if( SUCCEEDED(hr) && pRT ) { DDSURFACEDESC2 ddsd_rt; INITDDSTRUCT(ddsd_rt); ddsd_rt.dwFlags = DDSD_PIXELFORMAT; hr = pRT->GetSurfaceDesc( &ddsd_rt ); if( SUCCEEDED( hr )) { memcpy( (LPVOID)&(ddsd.ddpfPixelFormat), (LPVOID)&(ddsd_rt.ddpfPixelFormat), sizeof( DDPIXELFORMAT)); } if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32) { fmt = eX8R8G8B8; } else if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 ) { if( ddsd.ddpfPixelFormat.dwRBitMask == 0xF000 && ddsd.ddpfPixelFormat.dwGBitMask == 0x00F0 && ddsd.ddpfPixelFormat.dwBBitMask == 0x000F) { fmt = eX4R4G4B4; } else if ( ddsd.ddpfPixelFormat.dwRBitMask == 0xF800 && ddsd.ddpfPixelFormat.dwGBitMask == 0x7E0 && ddsd.ddpfPixelFormat.dwBBitMask == 0x1F ) { fmt = eR5G6B5; } } } if(FAILED(hr)) { ddsd.ddpfPixelFormat.dwFourCC = BI_RGB; ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwRGBBitCount = 16; ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xF000; ddsd.ddpfPixelFormat.dwRBitMask = 0x0F00; ddsd.ddpfPixelFormat.dwGBitMask = 0x00F0; ddsd.ddpfPixelFormat.dwBBitMask = 0x000F; fmt = eX4R4G4B4; } if( pRT ) { pRT->Release(); pRT = NULL; } // Create a new texture for the font hr = pDD->CreateSurface(&ddsd, &m_pTexture, NULL); if( FAILED(hr) ) return hr; // Prepare to create a bitmap DWORD * pBitmapBits; BITMAPINFO bmi; ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)m_dwTexWidth; bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a DC and a bitmap for the font HDC hDC = CreateCompatibleDC( NULL ); if( NULL == hDC ) return E_FAIL; HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0 ); SetMapMode( hDC, MM_TEXT ); // Create a font. By specifying ANTIALIASED_QUALITY, we might get an // antialiased font, but this is not guaranteed. INT nHeight = -MulDiv( m_dwFontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 ); DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL; DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE; HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_STRING_PRECIS, CLIP_STROKE_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, m_strFontName ); if( NULL==hFont ) return E_FAIL; SelectObject( hDC, hbmBitmap ); SelectObject( hDC, hFont ); // Set text properties SetTextColor( hDC, RGB(255,255,255) ); SetBkColor( hDC, 0x00000000 ); SetTextAlign( hDC, TA_TOP ); // Loop through all printable character and output them to the bitmap.. // Meanwhile, keep track of the corresponding tex coords for each character. DWORD x = 0; DWORD y = 0; TCHAR str[2] = _T("x"); SIZE size; for( TCHAR c=32; c<127; c++ ) { str[0] = c; GetTextExtentPoint32( hDC, str, 1, &size ); if( (DWORD)(x+size.cx+1) > m_dwTexWidth ) { x = 0; y += size.cy+1; } ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL ); m_fTexCoords[c-32][0] = ((FLOAT)(x+0))/m_dwTexWidth; m_fTexCoords[c-32][1] = ((FLOAT)(y+0))/m_dwTexHeight; m_fTexCoords[c-32][2] = ((FLOAT)(x+0+size.cx))/m_dwTexWidth; m_fTexCoords[c-32][3] = ((FLOAT)(y+0+size.cy))/m_dwTexHeight; x += size.cx+1; } if( fmt == eNull ) { OutputDebugString( TEXT("\n*** WARNING: This sample shows text only in one of the following formats: X8R8G8B8, X4R4G4B4, or R5G6B5. Text functions are DISABLED\n")); } // Lock the surface and write the alpha values for the set pixels m_pTexture->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); switch( fmt ) { case eX4R4G4B4: { WORD* pDst16 = (WORD*)ddsd.lpSurface; BYTE bAlpha; // 4-bit measure of pixel intensity for( y=0; y < m_dwTexHeight; y++ ) { for( x=0; x < m_dwTexWidth; x++ ) { bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (WORD) ((bAlpha << 12) | 0x0fff); } else { *pDst16++ = 0x0000; } } } } break; case eX8R8G8B8: { DWORD* pDst32 = (DWORD*)ddsd.lpSurface; BYTE bAlpha; // 4-bit measure of pixel intensity for( y=0; y < m_dwTexHeight; y++ ) { for( x=0; x < m_dwTexWidth; x++ ) { bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff)); if (bAlpha > 0) { *pDst32++ = (DWORD) ((bAlpha << 24) | 0x00ffffff); } else { *pDst32++ = 0x0000; } } } } break; case eR5G6B5: { WORD* pDst16 = (WORD*)ddsd.lpSurface; BYTE bAlpha; // 4-bit measure of pixel intensity for( y=0; y < m_dwTexHeight; y++ ) { for( x=0; x < m_dwTexWidth; x++ ) { bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 3); if (bAlpha > 0) { *pDst16++ = (WORD) ((bAlpha << 11) | (bAlpha << 6) | bAlpha); } else { *pDst16++ = 0x0000; } } } } }// switch // Done updating texture, so clean up used objects m_pTexture->Unlock(NULL); DeleteObject( hbmBitmap ); DeleteDC( hDC ); DeleteObject( hFont ); return S_OK; }
void CPPDrawManager::AlphaBitBlt(HDC hDestDC, int nDestX, int nDestY, DWORD dwWidth, DWORD dwHeight, HDC hSrcDC, int nSrcX, int nSrcY, int percent /* = 100 */) { _ASSERT ((NULL != hDestDC) || (NULL != hSrcDC)); if (percent >= 100) { ::BitBlt(hDestDC, nDestX, nDestY, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY); return; } //if HDC hTempDC = ::CreateCompatibleDC(hDestDC); if (NULL == hTempDC) return; //Creates Source DIB LPBITMAPINFO lpbiSrc; // Fill in the BITMAPINFOHEADER lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiSrc->bmiHeader.biWidth = dwWidth; lpbiSrc->bmiHeader.biHeight = dwHeight; lpbiSrc->bmiHeader.biPlanes = 1; lpbiSrc->bmiHeader.biBitCount = 32; lpbiSrc->bmiHeader.biCompression = BI_RGB; lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiSrc->bmiHeader.biXPelsPerMeter = 0; lpbiSrc->bmiHeader.biYPelsPerMeter = 0; lpbiSrc->bmiHeader.biClrUsed = 0; lpbiSrc->bmiHeader.biClrImportant = 0; COLORREF* pSrcBits = NULL; HBITMAP hSrcDib = CreateDIBSection ( hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits, NULL, NULL); if ((NULL != hSrcDib) && (NULL != pSrcBits)) { HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib); ::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); //Creates Destination DIB LPBITMAPINFO lpbiDest; // Fill in the BITMAPINFOHEADER lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiDest->bmiHeader.biWidth = dwWidth; lpbiDest->bmiHeader.biHeight = dwHeight; lpbiDest->bmiHeader.biPlanes = 1; lpbiDest->bmiHeader.biBitCount = 32; lpbiDest->bmiHeader.biCompression = BI_RGB; lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiDest->bmiHeader.biXPelsPerMeter = 0; lpbiDest->bmiHeader.biYPelsPerMeter = 0; lpbiDest->bmiHeader.biClrUsed = 0; lpbiDest->bmiHeader.biClrImportant = 0; COLORREF* pDestBits = NULL; HBITMAP hDestDib = CreateDIBSection ( hDestDC, lpbiDest, DIB_RGB_COLORS, (void **)&pDestBits, NULL, NULL); if ((NULL != hDestDib) && (NULL != pDestBits)) { ::SelectObject (hTempDC, hDestDib); ::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDestDC, nDestX, nDestY, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); double src_darken = (double)percent / 100.0; double dest_darken = 1.0 - src_darken; for (DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++) { *pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, dest_darken); } //for ::SelectObject (hTempDC, hDestDib); ::BitBlt (hDestDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); delete lpbiDest; ::DeleteObject(hDestDib); } //if delete lpbiSrc; ::DeleteObject(hSrcDib); } //if ::DeleteDC(hTempDC); } //End AlphaBitBlt
RawBitmap::RawBitmap(unsigned nWidth, unsigned nHeight) :width(nWidth), height(nHeight), corrected_width(CorrectedWidth(nWidth)) #ifdef ENABLE_OPENGL , texture(CorrectedWidth(nWidth), nHeight) #endif { assert(nWidth > 0); assert(nHeight > 0); #ifdef ENABLE_OPENGL buffer = new BGRColor[corrected_width * height]; #elif defined(ENABLE_SDL) Uint32 rmask, gmask, bmask, amask; int depth; #ifdef ANDROID rmask = 0x0000f800; gmask = 0x000007e0; bmask = 0x0000001f; depth = 16; #else rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0x000000ff; depth = 32; #endif amask = 0x00000000; assert(sizeof(BGRColor) * 8 == depth); surface = ::SDL_CreateRGBSurface(SDL_SWSURFACE, corrected_width, height, depth, rmask, gmask, bmask, amask); assert(!SDL_MUSTLOCK(surface)); buffer = (BGRColor *)surface->pixels; #else /* !ENABLE_SDL */ bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = corrected_width; bi.bmiHeader.biHeight = height; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = 0; bi.bmiHeader.biXPelsPerMeter = 3780; bi.bmiHeader.biYPelsPerMeter = 3780; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; #ifdef _WIN32_WCE /* configure 16 bit 5-5-5 on Windows CE */ bi.bmiHeader.biBitCount = 16; bi.bmiHeader.biCompression = BI_BITFIELDS; bi.bmiHeader.biClrUsed = 3; LPVOID p = &bi.bmiColors[0]; DWORD *q = (DWORD *)p; *q++ = 0x7c00; /* 5 bits red */ *q++ = 0x03e0; /* 5 bits green */ *q++ = 0x001f; /* 5 bits blue */ #endif #if defined(_WIN32_WCE) && _WIN32_WCE < 0x0400 /* StretchDIBits() is bugged on PPC2002, workaround follows */ VOID *pvBits; HDC hDC = ::GetDC(NULL); bitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0); ::ReleaseDC(NULL, hDC); buffer = (BGRColor *)pvBits; #else buffer = new BGRColor[corrected_width * height]; #endif #endif /* !ENABLE_SDL */ }
String MSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const { // get datator const char* src = (const char*)GlobalLock(data); if (src == NULL) { return String(); } UInt32 srcSize = (UInt32)GlobalSize(data); // check image type const BITMAPINFO* bitmap = reinterpret_cast<const BITMAPINFO*>(src); LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount)); if (bitmap->bmiHeader.biPlanes == 1 && (bitmap->bmiHeader.biBitCount == 24 || bitmap->bmiHeader.biBitCount == 32) && bitmap->bmiHeader.biCompression == BI_RGB) { // already in canonical form String image(src, srcSize); GlobalUnlock(data); return image; } // create a destination DIB section LOG((CLOG_INFO "convert image from: depth=%d comp=%d", bitmap->bmiHeader.biBitCount, bitmap->bmiHeader.biCompression)); void* raw; BITMAPINFOHEADER info; LONG w = bitmap->bmiHeader.biWidth; LONG h = bitmap->bmiHeader.biHeight; info.biSize = sizeof(BITMAPINFOHEADER); info.biWidth = w; info.biHeight = h; info.biPlanes = 1; info.biBitCount = 32; info.biCompression = BI_RGB; info.biSizeImage = 0; info.biXPelsPerMeter = 1000; info.biYPelsPerMeter = 1000; info.biClrUsed = 0; info.biClrImportant = 0; HDC dc = GetDC(NULL); HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO*)&info, DIB_RGB_COLORS, &raw, NULL, 0); // find the start of the pixel data const char* srcBits = (const char*)bitmap + bitmap->bmiHeader.biSize; if (bitmap->bmiHeader.biBitCount >= 16) { if (bitmap->bmiHeader.biCompression == BI_BITFIELDS && (bitmap->bmiHeader.biBitCount == 16 || bitmap->bmiHeader.biBitCount == 32)) { srcBits += 3 * sizeof(DWORD); } } else if (bitmap->bmiHeader.biClrUsed != 0) { srcBits += bitmap->bmiHeader.biClrUsed * sizeof(RGBQUAD); } else { //http://msdn.microsoft.com/en-us/library/ke55d167(VS.80).aspx srcBits += (1i64 << bitmap->bmiHeader.biBitCount) * sizeof(RGBQUAD); } // copy source image to destination image HDC dstDC = CreateCompatibleDC(dc); HGDIOBJ oldBitmap = SelectObject(dstDC, dst); SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h, srcBits, bitmap, DIB_RGB_COLORS); SelectObject(dstDC, oldBitmap); DeleteDC(dstDC); GdiFlush(); // extract data String image((const char*)&info, info.biSize); image.append((const char*)raw, 4 * w * h); // clean up GDI DeleteObject(dst); ReleaseDC(NULL, dc); // release handle GlobalUnlock(data); return image; }
////////////////////////////////////////////////////////////////////////// //函数名:BitmapToRegion //功能:输入图像句柄,得到抠除了蒙板色的区域 //原作者:Jean-Edouard Lachand Robert, August 5, 1998 //修改人:C瓜哥(www.cguage.com) HRGN CAnimateButton::BitmapToRegion(HBITMAP hBmp, int nSplit, int n, COLORREF cTransparentColor = RGB(255, 0, 255), COLORREF cTolerance = RGB(255, 0, 255)) { HRGN hRgn = NULL; if (hBmp) { // Create a memory DC inside which we will scan the bitmap content HDC hMemDC = CreateCompatibleDC(NULL); if (hMemDC) { // Get bitmap size BITMAP bm; GetObject(hBmp, sizeof(bm), &bm); // Create a 32 bits depth bitmap and select it into the memory DC BITMAPINFOHEADER RGB32BITSBITMAPINFO = { sizeof(BITMAPINFOHEADER), // biSize bm.bmWidth, // biWidth; bm.bmHeight, // biHeight; 1, // biPlanes; 32, // biBitCount BI_RGB, // biCompression; 0, // biSizeImage; 0, // biXPelsPerMeter; 0, // biYPelsPerMeter; 0, // biClrUsed; 0 // biClrImportant; }; //每种状态图的宽度 int nBlockWidth = bm.bmWidth / nSplit; VOID * pbits32; HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0); if (hbm32) { HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32); // Create a DC just to copy the bitmap into the memory DC HDC hDC = CreateCompatibleDC(hMemDC); if (hDC) { // Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits) BITMAP bm32; GetObject(hbm32, sizeof(bm32), &bm32); while (bm32.bmWidthBytes % 4) bm32.bmWidthBytes++; // Copy the bitmap into the memory DC HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp); BitBlt(hMemDC, 0, 0, nBlockWidth, bm.bmHeight, hDC, nBlockWidth * n, 0, SRCCOPY); // For better performances, we will use the ExtCreateRegion() function to create the // region. This function take a RGNDATA structure on entry. We will add rectangles by // amount of ALLOC_UNIT number in this structure. #define ALLOC_UNIT 100 DWORD maxRects = ALLOC_UNIT; HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects)); RGNDATA *pData = (RGNDATA *)GlobalLock(hData); pData->rdh.dwSize = sizeof(RGNDATAHEADER); pData->rdh.iType = RDH_RECTANGLES; pData->rdh.nCount = pData->rdh.nRgnSize = 0; SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); // Keep on hand highest and lowest values for the "transparent" pixels BYTE lr = GetRValue(cTransparentColor); BYTE lg = GetGValue(cTransparentColor); BYTE lb = GetBValue(cTransparentColor); BYTE hr = min(0xff, lr + GetRValue(cTolerance)); BYTE hg = min(0xff, lg + GetGValue(cTolerance)); BYTE hb = min(0xff, lb + GetBValue(cTolerance)); // Scan each bitmap row from bottom to top (the bitmap is inverted vertically) BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes; for (int y = 0; y < bm.bmHeight; y++) { // Scan each bitmap pixel from left to right for (int x = 0; x < nBlockWidth; x++) { // Search for a continuous range of "non transparent pixels" int x0 = x; LONG *p = (LONG *)p32 + x; while (x < nBlockWidth) { BYTE b = GetRValue(*p); if (b >= lr && b <= hr) { b = GetGValue(*p); if (b >= lg && b <= hg) { b = GetBValue(*p); if (b >= lb && b <= hb) // This pixel is "transparent" break; } } p++; x++; } if (x > x0) { // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region if (pData->rdh.nCount >= maxRects) { GlobalUnlock(hData); maxRects += ALLOC_UNIT; hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE); pData = (RGNDATA *)GlobalLock(hData); } RECT *pr = (RECT *)&pData->Buffer; SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1); if (x0 < pData->rdh.rcBound.left) pData->rdh.rcBound.left = x0; if (y < pData->rdh.rcBound.top) pData->rdh.rcBound.top = y; if (x > pData->rdh.rcBound.right) pData->rdh.rcBound.right = x; if (y+1 > pData->rdh.rcBound.bottom) pData->rdh.rcBound.bottom = y+1; pData->rdh.nCount++; // On Windows98, ExtCreateRegion() may fail if the number of rectangles is too // large (ie: > 4000). Therefore, we have to create the region by multiple steps. if (pData->rdh.nCount == 2000) { HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData); if (hRgn) { CombineRgn(hRgn, hRgn, h, RGN_OR); DeleteObject(h); } else hRgn = h; pData->rdh.nCount = 0; SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); } } } // Go to next row (remember, the bitmap is inverted vertically) p32 -= bm32.bmWidthBytes; } // Create or extend the region with the remaining rectangles HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData); if (hRgn) { CombineRgn(hRgn, hRgn, h, RGN_OR); DeleteObject(h); } else hRgn = h; // Clean up SelectObject(hDC, holdBmp); DeleteDC(hDC); } DeleteObject(SelectObject(hMemDC, holdBmp)); } DeleteDC(hMemDC); } }// if hBmp return hRgn; }
// Create a bitmap for off-screen drawing... bool CTinyCadView::CreateBitmap(CDC &dc, int width, int height) { // Is there already a suitable bitmap? if (m_bitmap_width >= width && m_bitmap_height >= height) { return true; } // Is this beyond the maximum size we are willing to allocate? if (width * height > m_max_bitmap_size) { return false; } int bpp = dc.GetDeviceCaps(BITSPIXEL); if (bpp <= 16) { bpp = 16; } else { bpp = 24; } // Now try and create the bitmap... struct { BITMAPINFO bi; RGBQUAD bipal[3]; } q; q.bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); q.bi.bmiHeader.biWidth = width; q.bi.bmiHeader.biHeight = height; q.bi.bmiHeader.biPlanes = 1; q.bi.bmiHeader.biBitCount = (WORD) bpp; q.bi.bmiHeader.biCompression = bpp == 16 ? BI_BITFIELDS : BI_RGB; q.bi.bmiHeader.biSizeImage = 0; q.bi.bmiHeader.biXPelsPerMeter = 0; q.bi.bmiHeader.biYPelsPerMeter = 0; q.bi.bmiHeader.biClrUsed = bpp == 16 ? 3 : 0; q.bi.bmiHeader.biClrImportant = 0; q.bi.bmiColors[0].rgbRed = 0; q.bi.bmiColors[0].rgbGreen = 0; q.bi.bmiColors[0].rgbBlue = 0; q.bi.bmiColors[0].rgbReserved = 0; // Set up the 5-6-5 bit masks if (bpp == 16) { ((DWORD*) (q.bi.bmiColors))[0] = (WORD) (0x1F << 11); //make sure that RGQQUAD array is after the q.bi struct ((DWORD*) (q.bi.bmiColors))[1] = (WORD) (0x3F << 5); //otherwise you will get an access violation ((DWORD*) (q.bi.bmiColors))[2] = (WORD) (0x1F << 0); } void *bits; HBITMAP hb = CreateDIBSection(dc.m_hDC, &q.bi, DIB_RGB_COLORS, &bits, NULL, 0); if (!hb) { // Probably not enough memory... return false; } // Do we need to destroy the old bitmap? if (m_bitmap.m_hObject) { m_bitmap.DeleteObject(); } m_bitmap.Attach(hb); m_bitmap_width = width; m_bitmap_height = height; return true; }
//Basic Init, create the font, backbuffer, etc WINDOW *initscr(void) { // _windows = new WINDOW[20]; //initialize all of our variables BITMAPINFO bmi; lastchar=-1; inputdelay=-1; std::string typeface; char * typeface_c; std::ifstream fin; fin.open("data\\FONTDATA"); if (!fin.is_open()){ MessageBox(WindowHandle, "Failed to open FONTDATA, loading defaults.", NULL, NULL); fontheight=16; fontwidth=8; } else { getline(fin, typeface); typeface_c= new char [typeface.size()+1]; strcpy (typeface_c, typeface.c_str()); fin >> fontwidth; fin >> fontheight; if ((fontwidth <= 4) || (fontheight <=4)){ MessageBox(WindowHandle, "Invalid font size specified!", NULL, NULL); fontheight=16; fontwidth=8; } } halfwidth=fontwidth / 2; halfheight=fontheight / 2; WindowWidth=80*fontwidth; WindowHeight=25*fontheight; WindowX=(GetSystemMetrics(SM_CXSCREEN) / 2)-WindowWidth/2; //center this WindowY=(GetSystemMetrics(SM_CYSCREEN) / 2)-WindowHeight/2; //sucker WinCreate(); //Create the actual window, register it, etc CheckMessages(); //Let the message queue handle setting up the window WindowDC = GetDC(WindowHandle); backbuffer = CreateCompatibleDC(WindowDC); ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = WindowWidth; bmi.bmiHeader.biHeight = -WindowHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount=8; bmi.bmiHeader.biCompression = BI_RGB; //store it in uncompressed bytes bmi.bmiHeader.biSizeImage = WindowWidth * WindowHeight * 1; bmi.bmiHeader.biClrUsed=16; //the number of colors in our palette bmi.bmiHeader.biClrImportant=16; //the number of colors in our palette backbit = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, (void**)&dcbits, NULL, 0); DeleteObject(SelectObject(backbuffer, backbit));//load the buffer into DC int nResults = AddFontResourceExA("data\\termfont",FR_PRIVATE,NULL); if (nResults>0){ font = CreateFont(fontheight, fontwidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_MODERN, typeface_c); //Create our font } else { MessageBox(WindowHandle, "Failed to load default font, using FixedSys.", NULL, NULL); font = CreateFont(fontheight, fontwidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_MODERN, "FixedSys"); //Create our font } //FixedSys will be user-changable at some point in time?? SetBkMode(backbuffer, TRANSPARENT);//Transparent font backgrounds SelectObject(backbuffer, font);//Load our font into the DC // WindowCount=0; delete typeface_c; mainwin = newwin(25,80,0,0); return mainwin; //create the 'stdscr' window and return its ref };
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S C R E E N S H O T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadSCREENSHOTImage() Takes a screenshot from the monitor(s). % % The format of the ReadSCREENSHOTImage method is: % % Image *ReadXImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadSCREENSHOTImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); image=(Image *) NULL; #if defined(MAGICKCORE_WINGDI32_DELEGATE) { BITMAPINFO bmi; DISPLAY_DEVICE device; HBITMAP bitmap, bitmapOld; HDC bitmapDC, hDC; Image *screen; int i; MagickBooleanType status; register Quantum *q; register ssize_t x; RGBQUAD *p; ssize_t y; assert(image_info != (const ImageInfo *) NULL); i=0; device.cb = sizeof(device); image=(Image *) NULL; while(EnumDisplayDevices(NULL,i,&device,0) && ++i) { if ((device.StateFlags & DISPLAY_DEVICE_ACTIVE) != DISPLAY_DEVICE_ACTIVE) continue; hDC=CreateDC(device.DeviceName,device.DeviceName,NULL,NULL); if (hDC == (HDC) NULL) ThrowReaderException(CoderError,"UnableToCreateDC"); screen=AcquireImage(image_info,exception); screen->columns=(size_t) GetDeviceCaps(hDC,HORZRES); screen->rows=(size_t) GetDeviceCaps(hDC,VERTRES); screen->storage_class=DirectClass; if (image == (Image *) NULL) image=screen; else AppendImageToList(&image,screen); status=SetImageExtent(screen,screen->columns,screen->rows,exception); if (status == MagickFalse) return(DestroyImageList(image)); bitmapDC=CreateCompatibleDC(hDC); if (bitmapDC == (HDC) NULL) { DeleteDC(hDC); ThrowReaderException(CoderError,"UnableToCreateDC"); } (void) memset(&bmi,0,sizeof(BITMAPINFO)); bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth=(LONG) screen->columns; bmi.bmiHeader.biHeight=(-1)*(LONG) screen->rows; bmi.bmiHeader.biPlanes=1; bmi.bmiHeader.biBitCount=32; bmi.bmiHeader.biCompression=BI_RGB; bitmap=CreateDIBSection(hDC,&bmi,DIB_RGB_COLORS,(void **) &p,NULL,0); if (bitmap == (HBITMAP) NULL) { DeleteDC(hDC); DeleteDC(bitmapDC); ThrowReaderException(CoderError,"UnableToCreateBitmap"); } bitmapOld=(HBITMAP) SelectObject(bitmapDC,bitmap); if (bitmapOld == (HBITMAP) NULL) { DeleteDC(hDC); DeleteDC(bitmapDC); DeleteObject(bitmap); ThrowReaderException(CoderError,"UnableToCreateBitmap"); } BitBlt(bitmapDC,0,0,(int) screen->columns,(int) screen->rows,hDC,0,0, SRCCOPY); (void) SelectObject(bitmapDC,bitmapOld); for (y=0; y < (ssize_t) screen->rows; y++) { q=QueueAuthenticPixels(screen,0,y,screen->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) screen->columns; x++) { SetPixelRed(image,ScaleCharToQuantum(p->rgbRed),q); SetPixelGreen(image,ScaleCharToQuantum(p->rgbGreen),q); SetPixelBlue(image,ScaleCharToQuantum(p->rgbBlue),q); SetPixelAlpha(image,OpaqueAlpha,q); p++; q+=GetPixelChannels(image); } if (SyncAuthenticPixels(screen,exception) == MagickFalse) break; } DeleteDC(hDC); DeleteDC(bitmapDC); DeleteObject(bitmap); } } #elif defined(MAGICKCORE_X11_DELEGATE) { const char *option; XImportInfo ximage_info; XGetImportInfo(&ximage_info); option=GetImageOption(image_info,"x:screen"); if (option != (const char *) NULL) ximage_info.screen=IsStringTrue(option); option=GetImageOption(image_info,"x:silent"); if (option != (const char *) NULL) ximage_info.silent=IsStringTrue(option); image=XImportImage(image_info,&ximage_info,exception); } #endif return(image); }
static void paintArea(HWND hwnd, void *data) { RECT xrect; PAINTSTRUCT ps; HDC hdc; HDC rdc; HBITMAP rbitmap, prevrbitmap; RECT rrect; BITMAPINFO bi; VOID *ppvBits; HBITMAP ibitmap; HDC idc; HBITMAP previbitmap; BLENDFUNCTION blendfunc; void *i; intptr_t dx, dy; int hscroll, vscroll; // FALSE here indicates don't send WM_ERASEBKGND if (GetUpdateRect(hwnd, &xrect, FALSE) == 0) return; // no update rect; do nothing getScrollPos(hwnd, &hscroll, &vscroll); hdc = BeginPaint(hwnd, &ps); if (hdc == NULL) xpanic("error beginning Area repaint", GetLastError()); // very big thanks to Ninjifox for suggesting this technique and helping me go through it // first let's create the destination image, which we fill with the windows background color // this is how we fake drawing the background; see also http://msdn.microsoft.com/en-us/library/ms969905.aspx rdc = CreateCompatibleDC(hdc); if (rdc == NULL) xpanic("error creating off-screen rendering DC", GetLastError()); // the bitmap has to be compatible with the window // if we create a bitmap compatible with the DC we just created, it'll be monochrome // thanks to David Heffernan in http://stackoverflow.com/questions/23033636/winapi-gdi-fillrectcolor-btnface-fills-with-strange-grid-like-brush-on-window rbitmap = CreateCompatibleBitmap(hdc, xrect.right - xrect.left, xrect.bottom - xrect.top); if (rbitmap == NULL) xpanic("error creating off-screen rendering bitmap", GetLastError()); prevrbitmap = (HBITMAP) SelectObject(rdc, rbitmap); if (prevrbitmap == NULL) xpanic("error connecting off-screen rendering bitmap to off-screen rendering DC", GetLastError()); rrect.left = 0; rrect.right = xrect.right - xrect.left; rrect.top = 0; rrect.bottom = xrect.bottom - xrect.top; if (FillRect(rdc, &rrect, areaBackgroundBrush) == 0) xpanic("error filling off-screen rendering bitmap with the system background color", GetLastError()); i = doPaint(&xrect, hscroll, vscroll, data, &dx, &dy); if (i == NULL) // cliprect empty goto nobitmap; // we need to blit the background no matter what // now we need to shove realbits into a bitmap // technically bitmaps don't know about alpha; they just ignore the alpha byte // AlphaBlend(), however, sees it - see http://msdn.microsoft.com/en-us/library/windows/desktop/dd183352%28v=vs.85%29.aspx ZeroMemory(&bi, sizeof (BITMAPINFO)); bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bi.bmiHeader.biWidth = (LONG) dx; bi.bmiHeader.biHeight = -((LONG) dy); // negative height to force top-down drawing bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = (DWORD) (dx * dy * 4); // this is all we need, but because this confused me at first, I will say the two pixels-per-meter fields are unused (see http://blogs.msdn.com/b/oldnewthing/archive/2013/05/15/10418646.aspx and page 581 of Charles Petzold's Programming Windows, Fifth Edition) // now for the trouble: CreateDIBSection() allocates the memory for us... ibitmap = CreateDIBSection(NULL, // Ninjifox does this, so do some wine tests (http://source.winehq.org/source/dlls/gdi32/tests/bitmap.c#L725, thanks vpovirk in irc.freenode.net/#winehackers) and even Raymond Chen (http://blogs.msdn.com/b/oldnewthing/archive/2006/11/16/1086835.aspx), so. &bi, DIB_RGB_COLORS, &ppvBits, 0, 0); if (ibitmap == NULL) xpanic("error creating HBITMAP for image returned by AreaHandler.Paint()", GetLastError()); // now we have to do TWO MORE things before we can finally do alpha blending // first, we need to load the bitmap memory, because Windows makes it for us // the pixels are arranged in RGBA order, but GDI requires BGRA // this turns out to be just ARGB in little endian; let's convert into this memory dotoARGB(i, (void *) ppvBits, FALSE); // FALSE = not NRGBA // the second thing is... make a device context for the bitmap :| // Ninjifox just makes another compatible DC; we'll do the same idc = CreateCompatibleDC(hdc); if (idc == NULL) xpanic("error creating HDC for image returned by AreaHandler.Paint()", GetLastError()); previbitmap = (HBITMAP) SelectObject(idc, ibitmap); if (previbitmap == NULL) xpanic("error connecting HBITMAP for image returned by AreaHandler.Paint() to its HDC", GetLastError()); // AND FINALLY WE CAN DO THE ALPHA BLENDING!!!!!!111 blendfunc.BlendOp = AC_SRC_OVER; blendfunc.BlendFlags = 0; blendfunc.SourceConstantAlpha = 255; // only use per-pixel alphas blendfunc.AlphaFormat = AC_SRC_ALPHA; // premultiplied if (AlphaBlend(rdc, 0, 0, (int) dx, (int) dy, // destination idc, 0, 0, (int) dx, (int)dy, // source blendfunc) == FALSE) xpanic("error alpha-blending image returned by AreaHandler.Paint() onto background", GetLastError()); // clean up after idc/ibitmap here because of the goto nobitmap if (SelectObject(idc, previbitmap) != ibitmap) xpanic("error reverting HDC for image returned by AreaHandler.Paint() to original HBITMAP", GetLastError()); if (DeleteObject(ibitmap) == 0) xpanic("error deleting HBITMAP for image returned by AreaHandler.Paint()", GetLastError()); if (DeleteDC(idc) == 0) xpanic("error deleting HDC for image returned by AreaHandler.Paint()", GetLastError()); nobitmap: // and finally we can just blit that into the window if (BitBlt(hdc, xrect.left, xrect.top, xrect.right - xrect.left, xrect.bottom - xrect.top, rdc, 0, 0, // from the rdc's origin SRCCOPY) == 0) xpanic("error blitting Area image to Area", GetLastError()); // now to clean up if (SelectObject(rdc, prevrbitmap) != rbitmap) xpanic("error reverting HDC for off-screen rendering to original HBITMAP", GetLastError()); if (DeleteObject(rbitmap) == 0) xpanic("error deleting HBITMAP for off-screen rendering", GetLastError()); if (DeleteDC(rdc) == 0) xpanic("error deleting HDC for off-screen rendering", GetLastError()); EndPaint(hwnd, &ps); }
Filename_notice *prepare_filename_notice(LPDIRECT3DDEVICE8 pd3dDevice, char const *filename) { HRESULT result; Filename_notice *notice = NULL; HDC hDC = NULL; HFONT hFont = NULL; SIZE size; int width, height; LPDIRECT3DTEXTURE8 pTexture = NULL; LPDIRECT3DVERTEXBUFFER8 pVB = NULL; DWORD *pBitmapBits = NULL; BITMAPINFO bmi; HBITMAP hbmBitmap = NULL; D3DLOCKED_RECT d3dlr; BYTE *pDstRow; int x, y; hDC = CreateCompatibleDC(NULL); SetMapMode(hDC, MM_TEXT); hFont = CreateFont( FONT_HEIGHT, // height 0, // width (0 = closest) 0, // escapement (0 = none) 0, // orientation (0 = none) FW_NORMAL, // bold FALSE, // italic FALSE, // underline FALSE, // strikeout DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, // TrueType (OUT_TT_PRECIS) doesn't help CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, FONT_NAME); if (hFont == NULL) { goto done; } // Set text properties SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); GetTextExtentPoint32(hDC, filename, strlen(filename), &size); width = size.cx; height = size.cy; // Create a new texture for the font result = pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &pTexture); if (FAILED(result)) { goto done; } // Prepare to create a bitmap ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; // negative means top-down bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0); SelectObject(hDC, hbmBitmap); ExtTextOut(hDC, 0, 0, ETO_OPAQUE, NULL, filename, strlen(filename), NULL); // Lock the surface and write the alpha values for the set pixels pTexture->LockRect(0, &d3dlr, 0, 0); pDstRow = (BYTE*)d3dlr.pBits; for (y = 0; y < height; y++) { WORD *pDst16 = (WORD *)pDstRow; for (x = 0; x < width; x++) { BYTE bAlpha = (BYTE)((pBitmapBits[width*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (WORD)((bAlpha << 12) | 0x0fff); } else { *pDst16++ = (WORD)(0x0000); } } pDstRow += d3dlr.Pitch; } // Done updating texture pTexture->UnlockRect(0); // Create vertices result = pd3dDevice->CreateVertexBuffer(4*sizeof(FONT2DVERTEX), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &pVB); if (FAILED(result)) { goto done; } notice = new Filename_notice; notice->width = width; notice->height = height; notice->pd3dDevice = pd3dDevice; notice->pTexture = pTexture; pTexture = NULL; notice->pVB = pVB; pVB = NULL; pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwSavedStateBlock); pd3dDevice->BeginStateBlock(); apply_render_state(pd3dDevice); pd3dDevice->SetTexture(0, notice->pTexture); pd3dDevice->EndStateBlock(¬ice->dwDrawTextStateBlock); done: if (pVB != NULL) { pVB->Release(); } if (pTexture != NULL) { pTexture->Release(); } if (hbmBitmap != NULL) { DeleteObject(hbmBitmap); } if (hFont != NULL) { DeleteObject(hFont); } if (hDC != NULL) { DeleteDC(hDC); } return notice; }
void CNtMagickView::DoDisplayImage() { CDC *pDC = GetDC(); if (pDC != NULL && m_Image.isValid() ) { CRect rectClient; GetClientRect(rectClient); // Clear the background pDC->FillSolidRect(rectClient,pDC->GetBkColor()); // Set up the Windows bitmap header BITMAPINFOHEADER bmi; bmi.biSize = sizeof(BITMAPINFOHEADER); // Size of structure bmi.biWidth = m_Image.columns(); // Bitmaps width in pixels bmi.biHeight = (-1)*m_Image.rows(); // Bitmaps height n pixels bmi.biPlanes = 1; // Number of planes in the image bmi.biBitCount = 32; // The number of bits per pixel bmi.biCompression = BI_RGB; // The type of compression used bmi.biSizeImage = 0; // The size of the image in bytes bmi.biXPelsPerMeter = 0; // Horizontal resolution bmi.biYPelsPerMeter = 0; // Veritical resolution bmi.biClrUsed = 0; // Number of colors actually used bmi.biClrImportant = 0; // Colors most important // Extract the pixels from Magick++ image object and convert to a DIB section Quantum *pPixels = m_Image.getPixels(0,0,m_Image.columns(),m_Image.rows()); RGBQUAD *prgbaDIB = 0; HBITMAP hBitmap = CreateDIBSection ( pDC->m_hDC, // handle to device context (BITMAPINFO *)&bmi, // pointer to structure containing bitmap size, format, and color data DIB_RGB_COLORS, // color data type indicator: RGB values or palette indices (void**)&prgbaDIB, // pointer to variable to receive a pointer to the bitmap's bit values NULL, // optional handle to a file mapping object 0 // offset to the bitmap bit values within the file mapping object ); if ( !hBitmap ) return; unsigned long nPixels = m_Image.columns() * m_Image.rows(); RGBQUAD *pDestPixel = prgbaDIB; // Transfer pixels, scaling to Quantum for( unsigned long nPixelCount = nPixels; nPixelCount ; nPixelCount-- ) { pDestPixel->rgbRed = MagickCore::GetPixelRed(m_Image.constImage(),pPixels)/257; pDestPixel->rgbGreen = MagickCore::GetPixelGreen(m_Image.constImage(),pPixels)/257; pDestPixel->rgbBlue = MagickCore::GetPixelBlue(m_Image.constImage(),pPixels)/257; pDestPixel->rgbReserved = 0; ++pDestPixel; pPixels+=MagickCore::GetPixelChannels(m_Image.constImage()); } // Now copy the bitmap to device. HDC hMemDC = CreateCompatibleDC( pDC->m_hDC ); SelectObject( hMemDC, hBitmap ); BitBlt( pDC->m_hDC, 0, 0, m_Image.columns(), m_Image.rows(), hMemDC, 0, 0, SRCCOPY ); DeleteObject( hMemDC ); } }
// // Since the transparent color for all LiteStep modules should be 0xFF00FF and // we are going to assume a tolerance of 0x000000, we can ignore the clrTransp // and clrTolerence parameter and hard code the values for the High and Low RGB // bytes The orginial code is commented out, if a module needs the removed // functionality, it should implement this function with the commented out code. HRGN BitmapToRegion( HBITMAP hbm, COLORREF clrTransp, COLORREF clrTolerance, int xoffset, int yoffset) { // start with a completely transparent rgn // this is more correct as no bmp, should render a transparent background HRGN hRgn = CreateRectRgn(0, 0, 0, 0); if (hbm) { // create a dc for the 32 bit dib HDC hdcMem = CreateCompatibleDC(NULL); if (hdcMem) { VOID *pbits32; HBITMAP hbm32; BITMAP bm; // get the size GetObject(hbm, sizeof(BITMAP), &bm); BITMAPINFOHEADER bmpInfo32; bmpInfo32.biSize = sizeof(BITMAPINFOHEADER); bmpInfo32.biWidth = bm.bmWidth; bmpInfo32.biHeight = bm.bmHeight; bmpInfo32.biPlanes = 1; bmpInfo32.biBitCount = 32; bmpInfo32.biCompression = BI_RGB; bmpInfo32.biSizeImage = 0; bmpInfo32.biXPelsPerMeter = 0; bmpInfo32.biYPelsPerMeter = 0; bmpInfo32.biClrUsed = 0; bmpInfo32.biClrImportant = 0; hbm32 = CreateDIBSection(hdcMem, (BITMAPINFO*)&bmpInfo32, DIB_RGB_COLORS, &pbits32, NULL, 0); if (hbm32) { HBITMAP hbmOld32 = (HBITMAP)SelectObject(hdcMem, hbm32); // Create a DC just to copy the bitmap into the memory D HDC hdcTmp = CreateCompatibleDC(hdcMem); if (hdcTmp) { // Get how many bytes per row we have for the bitmap bits // (rounded up to 32 bits) BITMAP bm32; GetObject(hbm32, sizeof(bm32), &bm32); while (bm32.bmWidthBytes % 4) { ++bm32.bmWidthBytes; } #if defined(LS_COMPAT_TRANSPTOL) // get the limits for the colors BYTE clrHiR = (0xff - GetRValue(clrTolerance)) > GetRValue(clrTransp) ? GetRValue(clrTransp) + GetRValue(clrTolerance) : 0xff; BYTE clrHiG = (0xff - GetGValue(clrTolerance)) > GetGValue(clrTransp) ? GetGValue(clrTransp) + GetGValue(clrTolerance) : 0xff; BYTE clrHiB = (0xff - GetBValue(clrTolerance)) > GetBValue(clrTransp) ? GetBValue(clrTransp) + GetBValue(clrTolerance) : 0xff; BYTE clrLoR = GetRValue(clrTolerance) < GetRValue(clrTransp) ? GetRValue(clrTransp) - GetRValue(clrTolerance) : 0x00; BYTE clrLoG = GetGValue(clrTolerance) < GetGValue(clrTransp) ? GetGValue(clrTransp) - GetGValue(clrTolerance) : 0x00; BYTE clrLoB = GetBValue(clrTolerance) < GetBValue(clrTransp) ? GetBValue(clrTransp) - GetBValue(clrTolerance) : 0x00; #endif // LS_COMPAT_TRANSPTOL // Copy the bitmap into the memory D HBITMAP hbmOld = (HBITMAP)SelectObject(hdcTmp, hbm); BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcTmp, 0, 0, SRCCOPY); // Scan each bitmap row from bottom to top // (the bitmap is inverted vertically) #if defined(LS_COMPAT_TRANSPTOL) BYTE *p; #else DWORD *p; #endif // LS_COMPAT_TRANSPTOL BYTE *p32 = (BYTE *)bm32.bmBits + \ (bm32.bmHeight - 1) * bm32.bmWidthBytes; int y = 0; while (y < bm.bmHeight) { int x = 0, x0; while (x < bm.bmWidth) { // loop through all transparent pixels... while (x < bm.bmWidth) { #if defined(LS_COMPAT_TRANSPTOL) p = p32 + 4 * x; // if the pixel is non-transparent, then break if (*p < clrLoB || *p > clrHiB) { break; } ++p; if (*p < clrLoG || *p > clrHiG) { break; } ++p; if (*p < clrLoR || *p > clrHiR) { break; } #else p = (DWORD*)(p32 + 4 * x); if (*p != 0xFF00FF) { break; } #endif // LS_COMPAT_TRANSPTOL ++x; } // save first non transparent pixel offset x0 = x; // loop through all non transparent pixels while (x < bm.bmWidth) { #if defined(LS_COMPAT_TRANSPTOL) p = p32 + 4 * x; // if the pixel is transparent, then break if (*p >= clrLoB && *p <= clrHiB) { ++p; if (*p >= clrLoG && *p <= clrHiG) { ++p; if (*p >= clrLoR && *p <= clrHiR) { break; } } } #else p = (DWORD*)(p32 + 4 * x); if (*p == 0xFF00FF) { break; } #endif // LS_COMPAT_TRANSPTOL ++x; } // if found one or more non-transparent pixels in a // row, add them to the rgn... if ((x - x0) > 0) { HRGN hTempRgn = CreateRectRgn( x0 + xoffset, y + yoffset, x + xoffset, y + 1 + yoffset); CombineRgn(hRgn, hRgn, hTempRgn, RGN_OR); DeleteObject(hTempRgn); } ++x; } ++y; p32 -= bm32.bmWidthBytes; } // Clean up SelectObject(hdcTmp, hbmOld); DeleteDC(hdcTmp); } SelectObject(hdcMem, hbmOld32); DeleteObject(hbm32); } DeleteDC(hdcMem); } } return hRgn; }
TW_UINT16 _get_gphoto2_file_as_DIB( const char *folder, const char *filename, CameraFileType type, HWND hwnd, HBITMAP *hDIB ) { const unsigned char *filedata; unsigned long filesize; int ret; CameraFile *file; struct jpeg_source_mgr xjsm; struct jpeg_decompress_struct jd; struct jpeg_error_mgr jerr; HDC dc; BITMAPINFO bmpInfo; LPBYTE bits, oldbits; JSAMPROW samprow, oldsamprow; if(!libjpeg_handle) { if(!load_libjpeg()) { FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); filedata = NULL; return TWRC_FAILURE; } } gp_file_new (&file); ret = gp_camera_file_get(activeDS.camera, folder, filename, type, file, activeDS.context); if (ret < GP_OK) { FIXME("Failed to get file?\n"); gp_file_unref (file); return TWRC_FAILURE; } ret = gp_file_get_data_and_size (file, (const char**)&filedata, &filesize); if (ret < GP_OK) { FIXME("Failed to get file data?\n"); return TWRC_FAILURE; } /* FIXME: Actually we might get other types than JPEG ... But only handle JPEG for now */ if (filedata[0] != 0xff) { ERR("File %s/%s might not be JPEG, cannot decode!\n", folder, filename); } /* This is basically so we can use in-memory data for jpeg decompression. * We need to have all the functions. */ xjsm.next_input_byte = filedata; xjsm.bytes_in_buffer = filesize; xjsm.init_source = _jpeg_init_source; xjsm.fill_input_buffer = _jpeg_fill_input_buffer; xjsm.skip_input_data = _jpeg_skip_input_data; xjsm.resync_to_restart = _jpeg_resync_to_restart; xjsm.term_source = _jpeg_term_source; jd.err = pjpeg_std_error(&jerr); /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h * jpeg_create_decompress(&jd); */ pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); jd.src = &xjsm; ret=pjpeg_read_header(&jd,TRUE); jd.out_color_space = JCS_RGB; pjpeg_start_decompress(&jd); if (ret != JPEG_HEADER_OK) { ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); gp_file_unref (file); return TWRC_FAILURE; } ZeroMemory (&bmpInfo, sizeof (BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = jd.output_width; bmpInfo.bmiHeader.biHeight = -jd.output_height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = jd.output_components*8; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; *hDIB = CreateDIBSection ((dc = GetDC(hwnd)), &bmpInfo, DIB_RGB_COLORS, (LPVOID)&bits, 0, 0); if (!*hDIB) { FIXME("Failed creating DIB.\n"); gp_file_unref (file); return TWRC_FAILURE; } samprow = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components); oldbits = bits; oldsamprow = samprow; while ( jd.output_scanline<jd.output_height ) { int i, x = pjpeg_read_scanlines(&jd,&samprow,1); if (x != 1) { FIXME("failed to read current scanline?\n"); break; } /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */ for(i=0;i<jd.output_width;i++,samprow+=jd.output_components) { *(bits++) = *(samprow+2); *(bits++) = *(samprow+1); *(bits++) = *(samprow); } bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3); samprow = oldsamprow; } if (hwnd) ReleaseDC (hwnd, dc); HeapFree (GetProcessHeap(), 0, samprow); gp_file_unref (file); return TWRC_SUCCESS; }
/*********************************************************************** * create_cgimage_from_icon * * Create a CGImage from a Windows icon. */ CGImageRef create_cgimage_from_icon(HANDLE icon, int width, int height) { CGImageRef ret = NULL; HDC hdc; char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *bitmapinfo = (BITMAPINFO*)buffer; unsigned char *color_bits, *mask_bits; HBITMAP hbmColor = 0, hbmMask = 0; int color_size, mask_size; TRACE("icon %p width %d height %d\n", icon, width, height); if (!width && !height) { ICONINFO info; BITMAP bm; if (!GetIconInfo(icon, &info)) return NULL; GetObjectW(info.hbmMask, sizeof(bm), &bm); if (!info.hbmColor) bm.bmHeight = max(1, bm.bmHeight / 2); width = bm.bmWidth; height = bm.bmHeight; TRACE("new width %d height %d\n", width, height); DeleteObject(info.hbmColor); DeleteObject(info.hbmMask); } hdc = CreateCompatibleDC(0); bitmapinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapinfo->bmiHeader.biWidth = width; bitmapinfo->bmiHeader.biHeight = -height; bitmapinfo->bmiHeader.biPlanes = 1; bitmapinfo->bmiHeader.biCompression = BI_RGB; bitmapinfo->bmiHeader.biXPelsPerMeter = 0; bitmapinfo->bmiHeader.biYPelsPerMeter = 0; bitmapinfo->bmiHeader.biClrUsed = 0; bitmapinfo->bmiHeader.biClrImportant = 0; bitmapinfo->bmiHeader.biBitCount = 32; color_size = width * height * 4; bitmapinfo->bmiHeader.biSizeImage = color_size; hbmColor = CreateDIBSection(hdc, bitmapinfo, DIB_RGB_COLORS, (VOID **) &color_bits, NULL, 0); if (!hbmColor) { WARN("failed to create DIB section for cursor color data\n"); goto cleanup; } bitmapinfo->bmiHeader.biBitCount = 1; bitmapinfo->bmiColors[0].rgbRed = 0; bitmapinfo->bmiColors[0].rgbGreen = 0; bitmapinfo->bmiColors[0].rgbBlue = 0; bitmapinfo->bmiColors[0].rgbReserved = 0; bitmapinfo->bmiColors[1].rgbRed = 0xff; bitmapinfo->bmiColors[1].rgbGreen = 0xff; bitmapinfo->bmiColors[1].rgbBlue = 0xff; bitmapinfo->bmiColors[1].rgbReserved = 0; mask_size = ((width + 31) / 32 * 4) * height; bitmapinfo->bmiHeader.biSizeImage = mask_size; hbmMask = CreateDIBSection(hdc, bitmapinfo, DIB_RGB_COLORS, (VOID **) &mask_bits, NULL, 0); if (!hbmMask) { WARN("failed to create DIB section for cursor mask data\n"); goto cleanup; } ret = create_cgimage_from_icon_bitmaps(hdc, icon, hbmColor, color_bits, color_size, hbmMask, mask_bits, mask_size, width, height, 0); cleanup: if (hbmColor) DeleteObject(hbmColor); if (hbmMask) DeleteObject(hbmMask); DeleteDC(hdc); return ret; }
//Basic Init, create the font, backbuffer, etc WINDOW *curses_init(void) { // _windows = new WINDOW[20]; //initialize all of our variables lastchar=-1; inputdelay=-1; std::string typeface; char * typeface_c = 0; std::ifstream fin; fin.open("data\\FONTDATA"); if (!fin.is_open()) { MessageBox(WindowHandle, "Failed to open FONTDATA, loading defaults.", NULL, 0); fontheight = 16; fontwidth = 8; } else { getline(fin, typeface); typeface_c = new char [typeface.size()+1]; strcpy (typeface_c, typeface.c_str()); fin >> fontwidth; fin >> fontheight; if ((fontwidth <= 4) || (fontheight <=4)) { MessageBox(WindowHandle, "Invalid font size specified!", NULL, 0); fontheight = 16; fontwidth = 8; } } halfwidth=fontwidth / 2; halfheight=fontheight / 2; WindowWidth= (55 + (OPTIONS["VIEWPORT_X"] * 2 + 1)) * fontwidth; WindowHeight = (OPTIONS["VIEWPORT_Y"] * 2 + 1) *fontheight; WinCreate(); //Create the actual window, register it, etc timeBeginPeriod(1); // Set Sleep resolution to 1ms CheckMessages(); //Let the message queue handle setting up the window WindowDC = GetDC(WindowHandle); backbuffer = CreateCompatibleDC(WindowDC); BITMAPINFO bmi = BITMAPINFO(); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = WindowWidth; bmi.bmiHeader.biHeight = -WindowHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 8; bmi.bmiHeader.biCompression = BI_RGB; // Raw RGB bmi.bmiHeader.biSizeImage = WindowWidth * WindowHeight * 1; bmi.bmiHeader.biClrUsed = 16; // Colors in the palette bmi.bmiHeader.biClrImportant = 16; // Colors in the palette backbit = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, (void**)&dcbits, NULL, 0); DeleteObject(SelectObject(backbuffer, backbit));//load the buffer into DC // Load private fonts if (SetCurrentDirectory("data\\font")) { WIN32_FIND_DATA findData; for (HANDLE findFont = FindFirstFile(".\\*", &findData); findFont != INVALID_HANDLE_VALUE; ) { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // Skip folders AddFontResourceExA(findData.cFileName, FR_PRIVATE,NULL); } if (!FindNextFile(findFont, &findData)) { FindClose(findFont); break; } } SetCurrentDirectory("..\\.."); } // Use desired font, if possible font = CreateFont(fontheight, fontwidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_MODERN, typeface_c); SetBkMode(backbuffer, TRANSPARENT);//Transparent font backgrounds SelectObject(backbuffer, font);//Load our font into the DC // WindowCount=0; delete typeface_c; mainwin = newwin((OPTIONS["VIEWPORT_Y"] * 2 + 1),(55 + (OPTIONS["VIEWPORT_Y"] * 2 + 1)),0,0); return mainwin; //create the 'stdscr' window and return its ref }
HBITMAP Font::CreateFontBitmap( DWORD MaxTextureWidth, DWORD** Bitmap ) { // Establish the font and texture size m_fTextScale = 1.0f; // Draw fonts into texture without scaling // Large fonts need larger textures if( m_dwFontHeight > 60 ) m_dwTexWidth = m_dwTexHeight = 2048; else if( m_dwFontHeight > 30 ) m_dwTexWidth = m_dwTexHeight = 1024; else if( m_dwFontHeight > 15 ) m_dwTexWidth = m_dwTexHeight = 512; else m_dwTexWidth = m_dwTexHeight = 256; // If requested texture is too big, use a smaller texture and smaller font, // and scale up when rendering. if (m_dwTexWidth > MaxTextureWidth) { m_fTextScale = (FLOAT)MaxTextureWidth / (FLOAT)m_dwTexWidth; m_dwTexWidth = m_dwTexHeight = MaxTextureWidth; } // Prepare to create a bitmap DWORD* pBitmapBits; BITMAPINFO bmi; ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) ); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)m_dwTexWidth; bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a DC and a bitmap for the font HDC hDC = CreateCompatibleDC( NULL ); HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0 ); SetMapMode( hDC, MM_TEXT ); // Create a font. By specifying ANTIALIASED_QUALITY, we might get an // antialiased font, but this is not guaranteed. INT nHeight = -MulDiv( m_dwFontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 ); DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL; DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE; HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, m_strFontName ); if( NULL==hFont ) return NULL; SelectObject( hDC, hbmBitmap ); SelectObject( hDC, hFont ); // Set text properties SetTextColor( hDC, RGB(255,255,255) ); SetBkColor( hDC, 0x00000000 ); SetTextAlign( hDC, TA_TOP ); // Loop through all printable character and output them to the bitmap.. // Meanwhile, keep track of the corresponding tex coords for each character. DWORD x = 0; DWORD y = 0; TCHAR str[2] = _T("x"); SIZE size; // Calculate the spacing between characters based on line height GetTextExtentPoint32( hDC, TEXT(" "), 1, &size ); x = m_dwSpacing = (DWORD) ceil(size.cy * 0.3f); for( TCHAR c=32; c < NUMBER_OF_CHARACTERS; c++ ) { str[0] = c; GetTextExtentPoint32( hDC, str, 1, &size ); if( (DWORD)(x + size.cx + m_dwSpacing) > m_dwTexWidth ) { x = m_dwSpacing; y += size.cy+1; } ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL ); m_fTexCoords[c-32][0] = ((FLOAT)(x + 0 - m_dwSpacing))/m_dwTexWidth; m_fTexCoords[c-32][1] = ((FLOAT)(y + 0 + 0 ))/m_dwTexHeight; m_fTexCoords[c-32][2] = ((FLOAT)(x + size.cx + m_dwSpacing))/m_dwTexWidth; m_fTexCoords[c-32][3] = ((FLOAT)(y + size.cy + 0 ))/m_dwTexHeight; x += size.cx + (2 * m_dwSpacing); } // Clean up used objects //DeleteObject( hbmBitmap ); DeleteDC( hDC ); DeleteObject( hFont ); *Bitmap = pBitmapBits; return hbmBitmap; }
bool COverlaySurfaceCache::CaptureFromSharedMemory(HDC hdc,LPCRECT prcDest) { if(prcDest ==0 ) return false; static CFileMapping shared_flags; //1.create filemapping object for sharing memory if(!shared_flags.IsOpen()) { if(!shared_flags.Open(kFlagsShareMemory,sizeof(DWORD),false )) { DebugOutF(filelog::log_error,"open shared_flags failed,could not open shared memory"); return false; } } DWORD *pFlags = (DWORD *)shared_flags.GetPointer(); if(*pFlags == 0) return false; TrackDebugOut; static LONG tick = GetTickCount();//make sure that message HWND_BROADCAST will be handle once. static CFileMapping mem; //1.create filemapping object for sharing memory if(!mem.IsOpen()) { if(!mem.Open(kChaptureOverlayShareMemory,sizeof(SURFACE_DATA),true )) { DebugOutF(filelog::log_error,"CaptureFromSharedMemory failed,could not open shared memory"); return false; } //2.Notify processes which using DirectDaw overlay. SURFACE_DATA*pDate = static_cast<SURFACE_DATA*>( mem.GetPointer()); pDate->modified = FALSE; SendMessageTimeout(HWND_BROADCAST,CAPTURE_SCREEN,++tick,0,SMTO_ABORTIFHUNG,10000,0); if(!pDate->modified) { DebugOutF(filelog::log_debug,"no overlay alive"); return false; } } // resize shared memory if necessarily int i = 0; for(i=0;i<3;++i) { SURFACE_DATA*pDate = static_cast<SURFACE_DATA*>( mem.GetPointer()); if(pDate->size + sizeof(SURFACE_DATA ) > mem.GetSize() ) { if(!mem.Open(kChaptureOverlayShareMemory,pDate->size + sizeof(SURFACE_DATA ),true )) { DebugOutF(filelog::log_error,"CaptureFromSharedMemory failed,could not open shared memory"); return false; } pDate = static_cast<SURFACE_DATA*>( mem.GetPointer()); } //Notify processes which using DirectDaw overlay. pDate->modified = FALSE; SendMessageTimeout(HWND_BROADCAST,CAPTURE_SCREEN,++tick,0,SMTO_ABORTIFHUNG,10000,0); if(!pDate->modified ) { DebugOutF(filelog::log_debug,"no overlay alive"); return false; } if(pDate->size + sizeof(SURFACE_DATA ) > mem.GetSize() ) continue; break; } /*return false;*/ if(i == 3) return false; CAutoLockEx<CMutexLock> lock(g_mLock); //open and get the size of shared memory //CFileMapping mem; // if(!mem.Open(kChaptureOverlayShareMemory,sizeof(SURFACE_DATA),false)) // { // DebugOutF(filelog::log_error,"CaptureFromSharedMemory failed,could not open shared memory"); // return false; // } // SURFACE_DATA* pData = (SURFACE_DATA*)mem.GetPointer(); // DWORD size = pData->size; // mem.Destroy(); // if(size < sizeof(SURFACE_DATA)) return false; // // then get open again with the size // if(!mem.Open(kChaptureOverlayShareMemory,size,false)) // { // DebugOutF(filelog::log_error,"CaptureFromSharedMemory failed,could not open shared memory as size %d",size); // return false; // } SURFACE_DATA*pData = (SURFACE_DATA*)mem.GetPointer(); // the area to be copy RECT dest ={0},src={0},intersect={0}; if(IsRectEmpty(&pData->rcDst)) { DebugOutF(filelog::log_debug,"CaptureFromSharedMemory dest rect is empty"); return true; } IntersectRect(&intersect,prcDest,&pData->rcDst); if(IsRectEmpty(&intersect)) { DebugOutF(filelog::log_debug,"CaptureFromSharedMemory dest rect is empty"); return true; } HRGN hrgn = 0; HBITMAP hBmp = 0; HDC hMemDC = 0; dest.left = intersect.left - prcDest->left; dest.top = intersect.top - prcDest->top; int w = intersect.right-intersect.left; int h = intersect.bottom-intersect.top; dest.right = dest.left +w; dest.bottom = dest.top +h; src.left = (intersect.left - pData->rcDst.left)*pData->desc.dwWidth/(pData->rcDst.right-pData->rcDst.left); src.top = (intersect .top -pData->rcDst.top)*pData->desc.dwHeight/(pData->rcDst.bottom-pData->rcDst.top); w = w*pData->desc.dwWidth/(pData->rcDst.right-pData->rcDst.left); h = h*pData->desc.dwHeight/(pData->rcDst.bottom-pData->rcDst.top); src.right = src.left +w; src.bottom = src.top +h; bool bOK = true; try { if (pData->desc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { DebugOutF(filelog::log_error,"unsupport color space 0x%x",pData->desc.ddpfPixelFormat.dwFourCC); throw false; } // if(pData->rdh.nCount ) // { // hrgn = ExtCreateRegion(0,pData->rdh.nRgnSize,(RGNDATA*)&pData->rdh); // if(prcDest) OffsetRgn(hrgn,-prcDest->left,-prcDest->top); // SelectClipRgn(hdc,hrgn); // } { BITMAPINFOHEADER infhead ; ZeroMemory(&infhead,sizeof(infhead)); infhead.biSize = sizeof(BITMAPINFOHEADER); infhead.biBitCount = (WORD)pData->desc.ddpfPixelFormat.dwRGBBitCount; int imagesize = pData->desc.lPitch* pData->desc.dwHeight; infhead.biPlanes = 1; infhead.biHeight = -LONG(pData->desc.dwHeight); infhead.biWidth = pData->desc.dwWidth; infhead.biSizeImage = imagesize ; infhead.biCompression = BI_RGB; hMemDC = CreateCompatibleDC(hdc); if(hMemDC == NULL){ DebugOutF(filelog::log_error,"CreateCompatibleDC failed with %d",GetLastError()); throw false; } { hBmp = CreateDIBSection(hMemDC, (BITMAPINFO *)&infhead, DIB_RGB_COLORS, 0,mem.GetHandle(), FIELD_OFFSET(SURFACE_DATA,data) + (pData->rdh.nRgnSize?pData->rdh.nRgnSize-sizeof(RGNDATAHEADER):0)); if(hBmp == NULL){ DebugOutF(filelog::log_error,"CreateDIBSection failed with %d",GetLastError() ); throw false; } } SelectObject(hMemDC,hBmp); if (((dest.right-dest.left) == (src.right-src.left)) && ((dest.bottom-dest.top) == (src.bottom-src.top)) ) { if(!BitBlt( hdc, dest.left, dest.top, dest.right-dest.left, dest.bottom-dest.top, hMemDC, src.left, src.top, SRCCOPY)) { DebugOutF( filelog::log_error,"StretchBlt failed with %d",GetLastError() ); throw false; } } else { if(!StretchBlt (hdc, dest.left, dest.top, dest.right-dest.left, dest.bottom-dest.top, hMemDC, src.left, src.top, src.right-src.left, src.bottom-src.top, SRCCOPY)) { DebugOutF(filelog::log_error,"StretchBlt failed with %d",GetLastError()); throw false; } } // DebugOutF(filelog::log_info,"CaptureFromSharedMemory (w:%d,h:%d,FourCC:0x%x,RGBBitCount:%d,l:%d,t:%d,r:%d,b:%d)ok", // pData->desc.dwWidth, // pData->desc.dwHeight, // pData->desc.ddpfPixelFormat.dwFourCC, // pData->desc.ddpfPixelFormat.dwRGBBitCount, // pData->rcDst.left, // pData->rcDst.top, // pData->rcDst.right, // pData->rcDst.bottom // ); //return true; } } catch (bool b1) { bOK = b1; } if(hMemDC)DeleteDC(hMemDC); if(hBmp)DeleteObject(hBmp); if(hrgn)DeleteObject(hrgn); DebugOutF(filelog::log_debug,"CaptureFromSharedMemory ok"); return bOK; }
HRESULT cFont::InitDeviceObjects(LPDIRECT3DDEVICE9 pDevice) { HRESULT hr; this->m_pDevice= pDevice; m_fTextScale = 1.0f; if (dwFontHeight > 40)dwWidth = dwHeight = 1024; else if (dwFontHeight > 20)dwWidth = dwHeight = 512; else dwWidth = dwHeight = 256; D3DCAPS9 d3dCaps; pDevice->GetDeviceCaps(&d3dCaps); if (dwWidth > d3dCaps.MaxTextureWidth) { m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)dwWidth; dwWidth =dwHeight = d3dCaps.MaxTextureWidth; } hr = pDevice->CreateTexture(dwWidth, dwHeight, 1,0, D3DFMT_A4R4G4B4,D3DPOOL_MANAGED, &m_pTexture, 0); if (FAILED(hr))return hr; DWORD* pBitmapBits; BITMAPINFO bmi; ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)dwWidth; bmi.bmiHeader.biHeight = -(int)dwHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; HDC hDC = CreateCompatibleDC(NULL); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0); SetMapMode(hDC, MM_TEXT); INT nHeight = -MulDiv(dwFontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72); DWORD dwBold = (dwFontFlags & D3DFONT_BOLD) ? FW_EXTRABOLD : FW_NORMAL; DWORD dwItalic = (dwFontFlags & D3DFONT_ITALIC) ? TRUE : FALSE; HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, strFontName); if (NULL == hFont) return E_FAIL; HGDIOBJ hPrevBitmap = SelectObject(hDC, hbmBitmap); HGDIOBJ hPrevFont = SelectObject(hDC, hFont); SetTextColor(hDC, RGB(255, 255, 255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); DWORD x = 0; DWORD y = 0; char str[2] = "x"; SIZE size; for (int c = 32; c <= MAX_CHAR_INDEX; c++) { str[0] = c; GetTextExtentPoint32A(hDC, str, 1, &size); if ((DWORD)(x + size.cx + 1) > dwWidth) { x = 0; y += size.cy + 1; } ExtTextOutA(hDC, x + 0, y + 0, ETO_OPAQUE, NULL, str, 1, NULL); m_fTexCoords[c - 32][0] = ((FLOAT)(x + 0)) / dwWidth; m_fTexCoords[c - 32][1] = ((FLOAT)(y + 0)) / dwWidth; m_fTexCoords[c - 32][2] = ((FLOAT)(x + 0 + size.cx)) / dwWidth; m_fTexCoords[c - 32][3] = ((FLOAT)(y + 0 + size.cy)) / dwWidth; x += size.cx + 1; } D3DLOCKED_RECT d3dlr; m_pTexture->LockRect(0, &d3dlr, 0, 0); BYTE* pDstRow = (BYTE*)d3dlr.pBits; WORD* pDst16; BYTE bAlpha; for (y = 0; y < dwHeight; y++) { pDst16 = (WORD*)pDstRow; for (x = 0; x < dwWidth; x++) { bAlpha = (BYTE)((pBitmapBits[dwWidth*y + x] & 0xff) >> 4); if (bAlpha > 0) { *pDst16++ = (bAlpha << 12) | 0x0fff; } else { *pDst16++ = 0x0000; } } pDstRow += d3dlr.Pitch; } m_pTexture->UnlockRect(0); SelectObject(hDC, hPrevBitmap); SelectObject(hDC, hPrevFont); DeleteObject(hbmBitmap); DeleteDC(hDC); DeleteObject(hFont); return S_OK; }
OLECONTAINER(void)::Draw(HDC hdcDraw, const RECT *rcDraw, BOOL bErase) { HWND hwnd = GetHWND(); HRESULT hr; RECT r; IOleObject *lpO = m_lpO; IViewObject *lpV = m_lpViewObjectEx ? (IViewObject *)m_lpViewObjectEx : m_lpViewObject; if (!m_bTransparent) { RECT rTotal; ::GetClientRect(hwnd, &rTotal); if (lpV) { if (!hdcDraw) { hdcDraw = ::GetDC(hwnd); hr = OleDraw(lpV, DVASPECT_CONTENT, hdcDraw, &rTotal); ::ReleaseDC(hwnd, hdcDraw); } else { hr = OleDraw(lpV, DVASPECT_CONTENT, hdcDraw, &rTotal); } } return; } ::GetWindowRect(hwnd, &r); if (!m_hdcBack || !EqualRect(&r, &m_rcBounds)) { if (m_hdcBack) ::DeleteDC(m_hdcBack); if (m_bmpBack) ::DeleteObject(m_bmpBack); if (m_hdcBackW) ::DeleteDC(m_hdcBackW); if (m_bmpBackW) ::DeleteObject(m_bmpBackW); m_rcBounds = r; HDC hdc = ::GetDC(hwnd); BITMAPINFOHEADER bih = {0}; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biPlanes = 1; bih.biWidth = r.right - r.left; bih.biHeight = -(r.bottom - r.top); m_hdcBack = CreateCompatibleDC(hdc); m_bmpBack = CreateDIBSection(hdc, (BITMAPINFO *)&bih, DIB_RGB_COLORS, (void **)&m_lpBitsOnly, NULL, 0x0); SelectObject(m_hdcBack, m_bmpBack); if (m_bFixTransparency) { m_hdcBackW = CreateCompatibleDC(hdc); m_bmpBackW = CreateDIBSection(hdc, (BITMAPINFO *)&bih, DIB_RGB_COLORS, (void **)&m_lpBitsOnlyW, NULL, 0x0); SelectObject(m_hdcBackW, m_bmpBackW); } ::ReleaseDC(hwnd, hdc); if (m_iBPP == 0) m_iBPP = GetDeviceCaps(m_hdcBack, BITSPIXEL); } POINT p = {r.left, r.top}; POINT p2 = {0, 0}; SIZE sz = {r.right-r.left, r.bottom-r.top}; if (lpO && lpV) { RECT rTotal; ::GetClientRect(hwnd, &rTotal); RECTL rcBounds = {rTotal.left, rTotal.top, rTotal.right, rTotal.bottom}; BYTE *dst = m_lpBitsOnly, *dstW; if (m_iBPP == 32) { if (!m_bFixTransparency) //if flash player version is other than 8, do usual painting { memset(m_lpBitsOnly, 0, sz.cx * sz.cy * 4); hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal); } else //if player version is 8, we need to fix flash player 8 control transparency bug { memset(m_lpBitsOnly, 0, sz.cx * sz.cy * 4); memset(m_lpBitsOnlyW, 255, sz.cx * sz.cy * 4); hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal); hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBackW, &rTotal); dst = m_lpBitsOnly; dstW = m_lpBitsOnlyW; BYTE r, g, b, a, rw, gw, bw, aw, alpha_r, alpha_g, alpha_b, alpha; for (int y = 0; y < sz.cy; y++) { for (int x = 0; x < sz.cx; x++) { //the idea is that we draw the same data onto black and white DC's //and then calculate per pixel alpha based on difference, produced by alpha blending r = *dst++; g = *dst++; b = *dst++; a = *dst++; rw = *dstW++; gw = *dstW++; bw = *dstW++; aw = *dstW++; alpha_r = rw-r; alpha_g = gw-g; alpha_b = bw-b; //division by 3 is for accuracy and can be replaced by //alpha = alpha_g; for example alpha = (alpha_r + alpha_g + alpha_b) / 3; *(dst - 1) = 255 - alpha; //this algorithm should be optimized for MMX to achieve best performance } } } } else //in 8/16/24 bit screen depth UpdateLayeredWindow produces wrong results - we use underlaying DC to paint to { //HWND hwndParent = ::GetParent(hwnd); HDC hdcParent = ::GetWindowDC(hwnd); BOOL bRet = BitBlt(m_hdcBack, 0, 0, rTotal.right, rTotal.bottom, hdcParent, 0, 0, SRCCOPY); ::ReleaseDC(hwnd, hdcParent); hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal); dst = m_lpBitsOnly; } } BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.AlphaFormat = AC_SRC_ALPHA; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; //BitBlt(hdcDraw, 0, 0, r.right-r.left, r.bottom-r.top, m_hdcBack, 0, 0, SRCCOPY); BOOL bRet = UpdateLayeredWindow(hwnd, NULL, &p, &sz, m_hdcBack, &p2, 0, &bf, /*m_iBPP == 32 ? ULW_ALPHA : */ULW_OPAQUE); }
void CWndShadow::Update(HWND hParent) { //int ShadSize = 5; //int Multi = 100 / ShadSize; RECT WndRect; GetWindowRect(hParent, &WndRect); int nShadWndWid = 0; int nShadWndHei = 0; if(m_pShadowImage != NULL) { // 九宫格方式,计算阴影窗口总的宽度和高度 nShadWndWid = WndRect.right - WndRect.left + m_nShadowWLT + m_nShadowWRB; nShadWndHei = WndRect.bottom - WndRect.top + m_nShadowHLT + m_nShadowHRB; }else { // 算法阴影方式,计算阴影窗口总的宽度和高度 nShadWndWid = WndRect.right - WndRect.left + m_nSize * 2; nShadWndHei = WndRect.bottom - WndRect.top + m_nSize * 2; } // Create the alpha blending bitmap BITMAPINFO bmi; // bitmap header ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = nShadWndWid; bmi.bmiHeader.biHeight = nShadWndHei; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; // four 8-bit components bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = nShadWndWid * nShadWndHei * 4; BYTE *pvBits; // pointer to DIB section HBITMAP hbitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pvBits, NULL, 0); HDC hMemDC = CreateCompatibleDC(NULL); HBITMAP hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap); if(m_pShadowImage != NULL) { // 九宫格方式画阴影图片 Graphics graphics(hMemDC); CRect rcTemp(0, 0, nShadWndWid, nShadWndHei); DrawImageFrameMID(graphics, m_pShadowImage, rcTemp, 0, 0, m_pShadowImage->GetWidth(), m_pShadowImage->GetHeight(), m_nShadowWLT, m_nShadowHLT, m_nShadowWRB+1, m_nShadowHRB+1); }else { // 画算法阴影 ZeroMemory(pvBits, bmi.bmiHeader.biSizeImage); MakeShadow((UINT32 *)pvBits, hParent, &WndRect); } // 计算阴影窗口偏移位置 POINT ptDst; if(m_pShadowImage != NULL) { ptDst.x = WndRect.left - m_nShadowWLT; ptDst.y = WndRect.top - m_nShadowHLT; } else { ptDst.x = WndRect.left + m_nxOffset - m_nSize; ptDst.y = WndRect.top + m_nyOffset - m_nSize; } POINT ptSrc = {0, 0}; SIZE WndSize = {nShadWndWid, nShadWndHei}; BLENDFUNCTION blendPixelFunction= { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; MoveWindow(m_hWnd, ptDst.x, ptDst.y, nShadWndWid, nShadWndHei, FALSE); BOOL bRet= s_UpdateLayeredWindow(m_hWnd, NULL, &ptDst, &WndSize, hMemDC, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); _ASSERT(bRet); // something was wrong.... // Delete used resources SelectObject(hMemDC, hOriBmp); DeleteObject(hbitmap); DeleteDC(hMemDC); }
// window procedure LRESULT CALLBACK SpectrumWindowProc(HWND h, UINT m, WPARAM w, LPARAM l) { switch (m) { case WM_PAINT: if (GetUpdateRect(h,0,0)) { PAINTSTRUCT p; HDC dc; if (!(dc=BeginPaint(h,&p))) return 0; BitBlt(dc,0,0,SPECWIDTH,SPECHEIGHT,specdc,0,0,SRCCOPY); EndPaint(h,&p); } return 0; case WM_LBUTTONUP: specmode=(specmode+1)%4; // swap spectrum mode memset(specbuf,0,SPECWIDTH*SPECHEIGHT); // clear display return 0; case WM_CREATE: win=h; // initialize BASS recording (default device) if (!BASS_RecordInit(-1)) { Error("Can't initialize device"); return -1; } // start recording (44100hz mono 16-bit) if (!(chan=BASS_RecordStart(44100,1,0,&DuffRecording,0))) { Error("Can't start recording"); return -1; } { // create bitmap to draw spectrum in (8 bit for easy updating) BYTE data[2000]={0}; BITMAPINFOHEADER *bh=(BITMAPINFOHEADER*)data; RGBQUAD *pal=(RGBQUAD*)(data+sizeof(*bh)); int a; bh->biSize=sizeof(*bh); bh->biWidth=SPECWIDTH; bh->biHeight=SPECHEIGHT; // upside down (line 0=bottom) bh->biPlanes=1; bh->biBitCount=8; bh->biClrUsed=bh->biClrImportant=256; // setup palette for (a=1;a<128;a++) { pal[a].rgbGreen=256-2*a; pal[a].rgbRed=2*a; } for (a=0;a<32;a++) { pal[128+a].rgbBlue=8*a; pal[128+32+a].rgbBlue=255; pal[128+32+a].rgbRed=8*a; pal[128+64+a].rgbRed=255; pal[128+64+a].rgbBlue=8*(31-a); pal[128+64+a].rgbGreen=8*a; pal[128+96+a].rgbRed=255; pal[128+96+a].rgbGreen=255; pal[128+96+a].rgbBlue=8*a; } // create the bitmap specbmp=CreateDIBSection(0,(BITMAPINFO*)bh,DIB_RGB_COLORS,(void**)&specbuf,NULL,0); specdc=CreateCompatibleDC(0); SelectObject(specdc,specbmp); } // setup update timer (40hz) timer=timeSetEvent(25,25,(LPTIMECALLBACK)&UpdateSpectrum,0,TIME_PERIODIC); break; case WM_DESTROY: if (timer) timeKillEvent(timer); BASS_RecordFree(); if (specdc) DeleteDC(specdc); if (specbmp) DeleteObject(specbmp); PostQuitMessage(0); break; } return DefWindowProc(h, m, w, l); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { BITMAPINFO DIBinfo; HBITMAP hBitmap, hOldBitmap; HDC hDC; HENHMETAFILE hemf; Image *image; RECT rect; register ssize_t x; register PixelPacket *q; RGBQUAD *pBits, *ppBits; ssize_t height, width, y; image=AcquireImage(image_info); hemf=ReadEnhMetaFile(image_info->filename,&width,&height); if (hemf == (HENHMETAFILE) NULL) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((image->columns == 0) || (image->rows == 0)) { double y_resolution, x_resolution; y_resolution=DefaultResolution; x_resolution=DefaultResolution; if (image->y_resolution > 0) { y_resolution=image->y_resolution; if (image->units == PixelsPerCentimeterResolution) y_resolution*=CENTIMETERS_INCH; } if (image->x_resolution > 0) { x_resolution=image->x_resolution; if (image->units == PixelsPerCentimeterResolution) x_resolution*=CENTIMETERS_INCH; } image->rows=(size_t) ((height/1000.0/CENTIMETERS_INCH)*y_resolution+0.5); image->columns=(size_t) ((width/1000.0/CENTIMETERS_INCH)* x_resolution+0.5); } if (image_info->size != (char *) NULL) { ssize_t x; image->columns=width; image->rows=height; x=0; y=0; (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows); } if (image_info->page != (char *) NULL) { char *geometry; register char *p; MagickStatusType flags; ssize_t sans; geometry=GetPageGeometry(image_info->page); p=strchr(geometry,'>'); if (p == (char *) NULL) { flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor((image->columns*image->x_resolution)+ 0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor((image->rows*image->y_resolution)+0.5); } else { *p='\0'; flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor(((image->columns*image->x_resolution)/ DefaultResolution)+0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor(((image->rows*image->y_resolution)/ DefaultResolution)+0.5); } (void) flags; geometry=DestroyString(geometry); } hDC=GetDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } /* Initialize the bitmap header info. */ (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); DIBinfo.bmiHeader.biWidth=(LONG) image->columns; DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows; DIBinfo.bmiHeader.biPlanes=1; DIBinfo.bmiHeader.biBitCount=32; DIBinfo.bmiHeader.biCompression=BI_RGB; hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,NULL, 0); ReleaseDC(NULL,hDC); if (hBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } hDC=CreateCompatibleDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); if (hOldBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); DeleteDC(hDC); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } /* Initialize the bitmap to the image background color. */ pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { for (x=0; x < (ssize_t) image->columns; x++) { pBits->rgbRed=ScaleQuantumToChar(image->background_color.red); pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green); pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue); pBits++; } } rect.top=0; rect.left=0; rect.right=(LONG) image->columns; rect.bottom=(LONG) image->rows; /* Convert metafile pixels. */ PlayEnhMetaFile(hDC,hemf,&rect); pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,ScaleCharToQuantum(pBits->rgbRed)); SetPixelGreen(q,ScaleCharToQuantum(pBits->rgbGreen)); SetPixelBlue(q,ScaleCharToQuantum(pBits->rgbBlue)); SetPixelOpacity(q,OpaqueOpacity); pBits++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } DeleteEnhMetaFile(hemf); SelectObject(hDC,hOldBitmap); DeleteDC(hDC); DeleteObject(hBitmap); return(GetFirstImageInList(image)); }
int32 CFont::m_InitMaterial(void) { // Establish the font and texture size p_TextScale = 1.0f; // Draw fonts into texture without scaling // Large fonts need larger textures if (p_FontHeight > 40) p_TexWidth = p_TexHeight = 1024; else if (p_FontHeight > 20) p_TexWidth = p_TexHeight = 512; else p_TexWidth = p_TexHeight = 256; // If requested texture is too big, use a smaller texture and smaller font, // and scale up when rendering. D3DCAPS8 d3dCaps; p_RenderLib->p_Device->GetDeviceCaps(&d3dCaps); if (p_TexWidth > d3dCaps.MaxTextureWidth) { p_TextScale = (float4)d3dCaps.MaxTextureWidth / (float4)p_TexWidth; p_TexWidth = p_TexHeight = d3dCaps.MaxTextureWidth; } // setup del materiale da usare p_Texture=new CGraphicSurface(p_TexWidth, p_TexHeight, 32); // Prepare to create a bitmap int32 *pBitmapBits; BITMAPINFO bmi; ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int32)p_TexWidth; bmi.bmiHeader.biHeight = -(int32)p_TexHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a DC and a bitmap for the font HDC hDC = CreateCompatibleDC(NULL); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void **)&pBitmapBits, NULL, 0); SetMapMode(hDC, MM_TEXT); INT nHeight = -MulDiv(p_FontHeight, (INT)(GetDeviceCaps(hDC, LOGPIXELSY)*p_TextScale), 72); int32 dwBold = (p_FontFlags & FONT_BOLD) ? FW_BOLD : FW_NORMAL; int32 dwItalic = (p_FontFlags & FONT_ITALIC) ? TRUE : FALSE; HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, p_FontName); if (NULL==hFont) return(0); SelectObject(hDC, hbmBitmap); SelectObject(hDC, hFont); // Set text properties SetTextColor(hDC, RGB(255,255,255)); SetBkColor(hDC, 0x00000000); SetTextAlign(hDC, TA_TOP); // Loop through all printable character and output them to the bitmap.. // Meanwhile, keep track of the corresponding tex coords for each character. int32 x = 0; int32 y = 0; char8 str[2]; SIZE size; for (char8 c=32; c<127; c++) { str[0] = c; GetTextExtentPoint32(hDC, str, 1, &size); if ((int32)(x+size.cx+1) > p_TexWidth) { x = 0; y += size.cy+1; } ExtTextOut(hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL); p_TexCoords[c-32][0] = ((float4)(x+0))/p_TexWidth; p_TexCoords[c-32][1] = ((float4)(y+0))/p_TexHeight; p_TexCoords[c-32][2] = ((float4)(x+0+size.cx))/p_TexWidth; p_TexCoords[c-32][3] = ((float4)(y+0+size.cy))/p_TexHeight; x += size.cx+1; } int32 *pDst32=(int32 *)p_Texture->p_Pixels; uchar8 bAlpha; for (y=0; y<p_TexHeight; y++) { for (x=0; x<p_TexWidth; x++) { bAlpha = (uchar8)((pBitmapBits[p_TexWidth*y + x] & 0xff)); if (bAlpha > 0) *pDst32++ = (bAlpha << 24) | 0x00ffffff; else *pDst32++ = 0x00000000; } } DeleteObject(hbmBitmap); DeleteDC(hDC); DeleteObject(hFont); p_RenderLib->m_AddUpdate_AlphaTexture(p_Texture, 1); return(1); }
HBITMAP LoadPngImageFromResources( _In_ PCWSTR Name ) { UINT width = 0; UINT height = 0; UINT frameCount = 0; BOOLEAN isSuccess = FALSE; ULONG resourceLength = 0; HGLOBAL resourceHandle = NULL; HRSRC resourceHandleSource = NULL; WICInProcPointer resourceBuffer = NULL; BITMAPINFO bitmapInfo = { 0 }; HBITMAP bitmapHandle = NULL; PBYTE bitmapBuffer = NULL; IWICStream* wicStream = NULL; IWICBitmapSource* wicBitmapSource = NULL; IWICBitmapDecoder* wicDecoder = NULL; IWICBitmapFrameDecode* wicFrame = NULL; IWICImagingFactory* wicFactory = NULL; IWICBitmapScaler* wicScaler = NULL; WICPixelFormatGUID pixelFormat; WICRect rect = { 0, 0, 164, 164 }; __try { // Create the ImagingFactory if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory))) __leave; // Find the resource if ((resourceHandleSource = FindResource(PhLibImageBase, Name, L"PNG")) == NULL) __leave; // Get the resource length resourceLength = SizeofResource(PhLibImageBase, resourceHandleSource); // Load the resource if ((resourceHandle = LoadResource(PhLibImageBase, resourceHandleSource)) == NULL) __leave; if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL) __leave; // Create the Stream if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream))) __leave; // Initialize the Stream from Memory if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength))) __leave; if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder))) __leave; if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad))) __leave; // Get the Frame count if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1) __leave; // Get the Frame if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame))) __leave; // Get the WicFrame image format if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat))) __leave; // Check if the image format is supported: if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppRGBA)) // GUID_WICPixelFormat32bppPBGRA { wicBitmapSource = (IWICBitmapSource*)wicFrame; } else { IWICFormatConverter* wicFormatConverter = NULL; if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter))) __leave; if (FAILED(IWICFormatConverter_Initialize( wicFormatConverter, (IWICBitmapSource*)wicFrame, &GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom ))) { IWICFormatConverter_Release(wicFormatConverter); __leave; } // Convert the image to the correct format: IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource); IWICFormatConverter_Release(wicFormatConverter); IWICBitmapFrameDecode_Release(wicFrame); } bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfo.bmiHeader.biWidth = rect.Width; bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height); bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biCompression = BI_RGB; HDC hdc = CreateCompatibleDC(NULL); bitmapHandle = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0); ReleaseDC(NULL, hdc); // Check if it's the same rect as the requested size. //if (width != rect.Width || height != rect.Height) if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler))) __leave; if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant))) __leave; if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer))) __leave; isSuccess = TRUE; } __finally { if (wicScaler) { IWICBitmapScaler_Release(wicScaler); } if (wicBitmapSource) { IWICBitmapSource_Release(wicBitmapSource); } if (wicStream) { IWICStream_Release(wicStream); } if (wicDecoder) { IWICBitmapDecoder_Release(wicDecoder); } if (wicFactory) { IWICImagingFactory_Release(wicFactory); } if (resourceHandle) { FreeResource(resourceHandle); } } return bitmapHandle; }
BOOL CImagePng::LoadImagePng(char *szPngName) { try { if (szPngName == NULL||strlen(szPngName) >= sizeof(m_szPngName)) return FALSE; FILE* file = NULL; HDC hDC = NULL; png_structp png_ptr = NULL; png_infop info_ptr = NULL; do { file = fopen(szPngName,"rb"); if (file == NULL) break; hDC = ::CreateCompatibleDC(NULL); if (hDC == NULL) break; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (png_ptr == NULL) break; info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) break; setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, file); // 读文件 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0); // 得到文件的宽高色深 int width = png_get_image_width(png_ptr,info_ptr); int height = png_get_image_height(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); // 申请内存 int size = height*width*4; // row_pointers里边就是rgba数据 png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr); if (row_pointers == NULL) break; BITMAPINFO bmi; memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFO); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = size; unsigned char* bgra = NULL; m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS,(void**)&bgra,NULL,0); if (m_hBmp == NULL) break; int pos = 0; int nAlpha = 0; for(int i = 0; i < height; i++) { for(int j = 0; j < (4 * width); j += 4) { nAlpha = row_pointers[height-i-1][j + 3]; bgra[pos++] = (row_pointers[height-i-1][j + 2]*nAlpha+127)/255; // blue bgra[pos++] = (row_pointers[height-i-1][j + 1]*nAlpha+127)/255; // green bgra[pos++] = (row_pointers[height-i-1][j]*nAlpha+127)/255; // red bgra[pos++] = row_pointers[height-i-1][j + 3]; // alpha } } ::DeleteDC(hDC); png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(file); m_nWidth = width; m_nHeight = height; return TRUE; } while (FALSE); if (file != NULL) { fclose(file); file = NULL; } if (hDC != NULL) { ::DeleteDC(hDC); hDC = NULL; } if (m_hBmp != NULL) { ::DeleteObject(m_hBmp); m_hBmp = NULL; } if (png_ptr != NULL||info_ptr != NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, 0); png_ptr = NULL; info_ptr = NULL; } return FALSE; } catch(...) { } return FALSE; }
bool GetPageBits(CET_LoadInfo *pDecodeInfo) { bool result = false; if (!lWidth || !lHeight) { pDecodeInfo->nErrNumber = PGE_INVALID_IMGSIZE; return false; } GDIPlusData *pData = (GDIPlusData*)CALLOC(sizeof(GDIPlusData)); if (!pData) { pDecodeInfo->nErrNumber = PGE_NOT_ENOUGH_MEMORY; } else { pData->nMagic = eGdiStr_Bits; pData->pImg = this; pDecodeInfo->pFileContext = pData; wsprintf(pData->szInfo, L"%i x %i x %ibpp", lWidth, lHeight, nBPP); if (nPages > 1) wsprintf(pData->szInfo+lstrlen(pData->szInfo), L" [%i]", nPages); if (FormatName[0]) { lstrcat(pData->szInfo, L" "); lstrcat(pData->szInfo, FormatName); } int nCanvasWidth = pDecodeInfo->crLoadSize.X; int nCanvasHeight = pDecodeInfo->crLoadSize.Y; BOOL lbAllowThumb = (nFormatID == cfTIFF || nFormatID == cfTIFF || nFormatID == cfEXIF || nFormatID == cfJPEG); //&& (lWidth > (UINT)nCanvasWidth*5) && (lHeight > (UINT)nCanvasHeight*5); int nShowWidth, nShowHeight; CalculateShowSize(nCanvasWidth, nCanvasHeight, nShowWidth, nShowHeight, lbAllowThumb); // Получим из EXIF ориентацию int nOrient; if (!GetExifTagValueAsInt(PropertyTagOrientation, nOrient)) nOrient = 0; if (lbAllowThumb && nOrient) { Gdiplus::GpImage *thmb = NULL; // Сразу пытаемся извлечь в режиме превьюшки (полная картинка нам не нужна) Gdiplus::Status lRc = gdi->GdipGetImageThumbnail(img, nShowWidth, nShowHeight, &thmb, (Gdiplus::GetThumbnailImageAbort)DrawImageAbortCallback, gdi); if (thmb) { lRc = gdi->GdipDisposeImage(img); img = thmb; lRc = gdi->GdipGetImageWidth(img, &lWidth); lRc = gdi->GdipGetImageHeight(img, &lHeight); } // Теперь - крутим Gdiplus::RotateFlipType rft = Gdiplus::RotateNoneFlipNone; switch(nOrient) { case 3: rft = Gdiplus::Rotate180FlipNone; break; case 6: rft = Gdiplus::Rotate90FlipNone; break; case 8: rft = Gdiplus::Rotate270FlipNone; break; case 2: rft = Gdiplus::RotateNoneFlipX; break; case 4: rft = Gdiplus::RotateNoneFlipY; break; case 5: rft = Gdiplus::Rotate90FlipX; break; case 7: rft = Gdiplus::Rotate270FlipX; break; } if (rft) { lRc = gdi->GdipImageRotateFlip(img, rft); if (!lRc) { lRc = gdi->GdipGetImageWidth(img, &lWidth); lRc = gdi->GdipGetImageHeight(img, &lHeight); //-V519 nCanvasWidth = pDecodeInfo->crLoadSize.X; nCanvasHeight = pDecodeInfo->crLoadSize.Y; CalculateShowSize(nCanvasWidth, nCanvasHeight, nShowWidth, nShowHeight, lbAllowThumb); } } } nCanvasWidth = nShowWidth; nCanvasHeight = nShowHeight; int nCanvasWidthS = nCanvasWidth; //((nCanvasWidth+7) >> 3) << 3; // try to align x8 pixels pData->hCompDc1 = CreateCompatibleDC(NULL); BITMAPINFOHEADER bmi = {sizeof(BITMAPINFOHEADER)}; bmi.biWidth = nCanvasWidthS; bmi.biHeight = -nCanvasHeight; // Top-Down DIB bmi.biPlanes = 1; bmi.biBitCount = 32; bmi.biCompression = BI_RGB; LPBYTE pBits = NULL; pData->hDIB = CreateDIBSection(pData->hCompDc1, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0); if (!pData->hDIB) { _ASSERTE(pData->hDIB); } else { pData->hOld1 = (HBITMAP)SelectObject(pData->hCompDc1, pData->hDIB); RECT rcFull = {0,0,nCanvasWidthS, nCanvasHeight}; HBRUSH hBr = CreateSolidBrush(pDecodeInfo->crBackground); FillRect(pData->hCompDc1, &rcFull, hBr); DeleteObject(hBr); Gdiplus::GpGraphics *pGr = NULL; Gdiplus::Status stat = gdi->GdipCreateFromHDC(pData->hCompDc1, &pGr); if (!stat) { #ifdef _DEBUG if (nCanvasWidth!=nShowWidth || nCanvasHeight!=nShowHeight) { _ASSERTE(nCanvasWidth==nShowWidth && nCanvasHeight==nShowHeight); } #endif //int x = (nCanvasWidth-nShowWidth)>>1; //int y = (nCanvasHeight-nShowHeight)>>1; stat = gdi->GdipDrawImageRectRectI( pGr, img, 0, 0, nShowWidth, nShowHeight, 0, 0, lWidth, lHeight, Gdiplus::UnitPixel, NULL, //NULL, NULL); (Gdiplus::DrawImageAbort)DrawImageAbortCallback, gdi); gdi->GdipDeleteGraphics(pGr); } if (stat) { pDecodeInfo->nErrNumber = PGE_BITBLT_FAILED; } else { result = true; pDecodeInfo->pFileContext = (LPVOID)pData; pDecodeInfo->crSize.X = nCanvasWidth; pDecodeInfo->crSize.Y = nCanvasHeight; pDecodeInfo->cbStride = nCanvasWidthS * 4; pDecodeInfo->nBits = 32; pDecodeInfo->ColorModel = CET_CM_BGR; pDecodeInfo->pszComments = pData->szInfo; pDecodeInfo->cbPixelsSize = pDecodeInfo->cbStride * nCanvasHeight; pDecodeInfo->Pixels = (const DWORD*)pBits; } } pData->pImg = NULL; if (!result) { pDecodeInfo->pFileContext = this; pData->Close(); } } return result; };
//位图转换到区域 (需要重写) HRGN AFCBmpToRgn(HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance) { if (hBmp==NULL) return NULL; HRGN hRgn=NULL; HDC hMemDC=::CreateCompatibleDC(NULL); if (hMemDC!=NULL) { BITMAP bm; GetObject(hBmp, sizeof(bm), &bm); VOID * pbits32=NULL; BITMAPINFOHEADER RGB32BITSBITMAPINFO = {sizeof(BITMAPINFOHEADER),bm.bmWidth,bm.bmHeight,1,32,BI_RGB,0,0,0,0,0}; HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0); if (hbm32) { HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32); HDC hDC = CreateCompatibleDC(hMemDC); if (hDC) { BITMAP bm32; GetObject(hbm32,sizeof(bm32),&bm32); while (bm32.bmWidthBytes%4) bm32.bmWidthBytes++; HBITMAP holdBmp=(HBITMAP)SelectObject(hDC,hBmp); BitBlt(hMemDC,0,0,bm.bmWidth,bm.bmHeight,hDC,0,0,SRCCOPY); #define ALLOC_UNIT 100 DWORD maxRects=ALLOC_UNIT; HANDLE hData=GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects)); RGNDATA *pData=(RGNDATA *)GlobalLock(hData); pData->rdh.dwSize=sizeof(RGNDATAHEADER); pData->rdh.iType=RDH_RECTANGLES; pData->rdh.nCount=pData->rdh.nRgnSize=0; SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); // Keep on hand highest and lowest values for the "transparent" pixels BYTE lr = GetRValue(cTransparentColor); BYTE lg = GetGValue(cTransparentColor); BYTE lb = GetBValue(cTransparentColor); BYTE hr = min(0xff, lr + GetRValue(cTolerance)); BYTE hg = min(0xff, lg + GetGValue(cTolerance)); BYTE hb = min(0xff, lb + GetBValue(cTolerance)); // Scan each bitmap row from bottom to top (the bitmap is inverted vertically) BYTE *p32=(BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes; for (int y=0;y<bm.bmHeight;y++) { // Scan each bitmap pixel from left to right for (int x=0;x<bm.bmWidth;x++) { // Search for a continuous range of "non transparent pixels" int x0=x; LONG *p=(LONG *)p32+x; while (x<bm.bmWidth) { BYTE b=GetRValue(*p); if (b>=lr&&b<=hr) { b=GetGValue(*p); if (b>=lg&&b<=hg) { b = GetBValue(*p); if (b >= lb && b <= hb) break; } } p++; x++; } if (x>x0) { // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region if (pData->rdh.nCount >= maxRects) { GlobalUnlock(hData); maxRects += 100; hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE); pData = (RGNDATA *)GlobalLock(hData); } RECT *pr = (RECT *)&pData->Buffer; SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1); if (x0 < pData->rdh.rcBound.left) pData->rdh.rcBound.left = x0; if (y < pData->rdh.rcBound.top) pData->rdh.rcBound.top = y; if (x > pData->rdh.rcBound.right) pData->rdh.rcBound.right = x; if (y+1 > pData->rdh.rcBound.bottom) pData->rdh.rcBound.bottom = y+1; pData->rdh.nCount++; // On Windows98, ExtCreateRegion() may fail if the number of rectangles is too // large (ie: > 4000). Therefore, we have to create the region by multiple steps. if (pData->rdh.nCount == 2000) { HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData); if (hRgn) { CombineRgn(hRgn, hRgn, h, RGN_OR); DeleteObject(h); } else hRgn = h; pData->rdh.nCount = 0; SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0); } } } p32 -= bm32.bmWidthBytes; } HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData); if (hRgn) { CombineRgn(hRgn, hRgn, h, RGN_OR); DeleteObject(h); } else hRgn = h; // Clean up GlobalFree(hData); SelectObject(hDC, holdBmp); DeleteDC(hDC); } DeleteObject(SelectObject(hMemDC, holdBmp)); } DeleteDC(hMemDC); } return hRgn; }
//-------------------------------------------------------------------------- bool WindowsMouse::_CreateCursor(VeCursor::Data* pkCur, const VeSurfacePtr& spSurface, VeInt32 i32HotX, VeInt32 i32HotY) noexcept { VE_ASSERT(spSurface && pkCur); const VeSizeT pad = (sizeof(VeSizeT) * 8); HICON hicon; HDC hdc; BITMAPV4HEADER bmh; LPVOID pixels; LPVOID maskbits; size_t maskbitslen; ICONINFO ii; VeInt32 w = spSurface->GetWidth(); VeInt32 h = spSurface->GetHeight(); VeZeroMemory(&bmh, sizeof(bmh)); bmh.bV4Size = sizeof(bmh); bmh.bV4Width = w; bmh.bV4Height = -h; bmh.bV4Planes = 1; bmh.bV4BitCount = 32; bmh.bV4V4Compression = BI_BITFIELDS; bmh.bV4AlphaMask = 0xFF000000; bmh.bV4RedMask = 0x00FF0000; bmh.bV4GreenMask = 0x0000FF00; bmh.bV4BlueMask = 0x000000FF; maskbitslen = ((w + (pad - (w % pad))) / 8) * h; maskbits = VeStackAlloc(VeUInt8, maskbitslen); VeMemorySet(maskbits, 0xFF, maskbitslen); hdc = GetDC(nullptr); VeZeroMemory(&ii, sizeof(ii)); ii.fIcon = FALSE; ii.xHotspot = (DWORD)i32HotX; ii.yHotspot = (DWORD)i32HotY; ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, nullptr, 0); ii.hbmMask = CreateBitmap(w, h, 1, 1, maskbits); ReleaseDC(nullptr, hdc); VeStackFree(maskbits); VE_ASSERT(spSurface->GetFormat()->m_u32Format == VE_PIXELFORMAT_ARGB8888); VE_ASSERT(spSurface->GetPitch() == w * 4); VeMemoryCopy(pixels, spSurface->GetBuffer(), h * spSurface->GetPitch()); hicon = CreateIconIndirect(&ii); DeleteObject(ii.hbmColor); DeleteObject(ii.hbmMask); pkCur->m_pvDriverdata = hicon; if (!hicon) { return false; } return true; }
int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; size_t size; LPBITMAPINFO info; #ifdef HAVE_GETDIBITS HBITMAP hbm; #endif /* Free the old framebuffer surface */ if (data->mdc) { DeleteDC(data->mdc); } if (data->hbm) { DeleteObject(data->hbm); } /* Find out the format of the screen */ size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD); info = (LPBITMAPINFO)SDL_stack_alloc(Uint8, size); #ifdef HAVE_GETDIBITS SDL_memset(info, 0, size); info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); /* The second call to GetDIBits() fills in the bitfields */ hbm = CreateCompatibleBitmap(data->hdc, 1, 1); GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS); GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS); DeleteObject(hbm); *format = SDL_PIXELFORMAT_UNKNOWN; if (info->bmiHeader.biCompression == BI_BITFIELDS) { int bpp; Uint32 *masks; bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount; masks = (Uint32*)((Uint8*)info + info->bmiHeader.biSize); *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0); } if (*format == SDL_PIXELFORMAT_UNKNOWN) #endif { /* We'll use RGB format for now */ *format = SDL_PIXELFORMAT_RGB888; /* Create a new one */ SDL_memset(info, 0, size); info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 32; info->bmiHeader.biCompression = BI_RGB; } /* Fill in the size information */ *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); info->bmiHeader.biWidth = window->w; info->bmiHeader.biHeight = -window->h; /* negative for topdown bitmap */ info->bmiHeader.biSizeImage = window->h * (*pitch); data->mdc = CreateCompatibleDC(data->hdc); data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0); SDL_stack_free(info); if (!data->hbm) { WIN_SetError("Unable to create DIB"); return -1; } SelectObject(data->mdc, data->hbm); return 0; }