// window message processing procedure LRESULT CALLBACK WndAbout::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE: { // resize window so that client area := 400x300 { RECT cRect; RECT wRect; GetClientRect(hwnd, &cRect); GetWindowRect(hwnd, &wRect); uint32 difW = (wRect.right - wRect.left) - (cRect.right); uint32 difH = (wRect.bottom - wRect.top) - (cRect.bottom); MoveWindow(hwnd, wRect.left, wRect.top, difW + 400, difH + 300, TRUE); } EnableWindow(m_parent, FALSE); HDC hDC = GetDC(hwnd); int nHeight = -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72); m_hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_ROMAN, "Verdana"); m_BackBmp = CreateCompatibleBitmap(hDC, 400, 300); // decompress jpeg, convert to bitmap resource { HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(IDR_JPEG_ABOUT), "JPEG"); HGLOBAL hRes = LoadResource(NULL, hSrc); uint08 *jpgData = (uint08*)LockResource(hRes); uint32 jpgFileSize = SizeofResource(NULL, hSrc); uint32 bmpFileSize = 0; uint32 bmpWidth, bmpHeight; uint08 *bmpBuff = jpeg2bmp(jpgData, jpgFileSize, &bmpFileSize, &bmpWidth, &bmpHeight); // create bitmap { BITMAPINFO BmpInfo; BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFO) - sizeof(RGBQUAD); BmpInfo.bmiHeader.biWidth = bmpWidth; BmpInfo.bmiHeader.biHeight = 0 - (int)bmpHeight; BmpInfo.bmiHeader.biPlanes = 1; BmpInfo.bmiHeader.biBitCount = 24; 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; SetDIBits(hDC, m_BackBmp, 0, bmpHeight, bmpBuff, &BmpInfo, DIB_RGB_COLORS); } free(bmpBuff); UnlockResource(hRes); } m_BackDC = CreateCompatibleDC(hDC); m_OrigBmp = (HBITMAP)SelectObject(m_BackDC, m_BackBmp); ReleaseDC(hwnd, hDC); SetClassLong(hwnd, GCL_HICON, (LONG)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_CXBX))); } break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hwnd, &ps); HDC hDC = GetDC(hwnd); HGDIOBJ OrgObj = SelectObject(hDC, m_hFont); // draw bitmap BitBlt(hDC, 0, 0, 400, 300, m_BackDC, 0, 0, SRCCOPY); SelectObject(hDC, OrgObj); if(hDC != NULL) ReleaseDC(hwnd, hDC); EndPaint(hwnd, &ps); } break; case WM_LBUTTONUP: SendMessage(hwnd, WM_CLOSE, 0, 0); break; case WM_CLOSE: EnableWindow(m_parent, TRUE); DestroyWindow(hwnd); break; case WM_DESTROY: DeleteObject(m_hFont); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; }
void Stato::newVideoMessage(char *header,BYTE *buf) { if(header && buf) { // received WM_VIDEO -> new data, save it in hdc_mem and then update the image showed /* byte 2,3: coord x byte 4,5: coord y byte 6,7: width (px) byte 8,9: height (px) byte 10,11: bytes per pixel */ int x,y,width,height,size,bytesperpixel; memcpy(&x, header + 2,2); memcpy(&y, header + 4,2); memcpy(&width, header + 6,2); memcpy(&height, header + 8,2); memcpy(&bytesperpixel, header + 10,2); x=ntohs(x); y=ntohs(y); width=ntohs(width); height=ntohs(height); bytes_per_pixel=ntohs(bytesperpixel); size=width*height*bytes_per_pixel; HDC hdc_tmp = CreateCompatibleDC(NULL); HBITMAP bitmap = CreateCompatibleBitmap(hdcBuf,width,height); BITMAPINFOHEADER bmih; bmih.biSize = sizeof(BITMAPINFOHEADER); bmih.biBitCount = 8*bytes_per_pixel; bmih.biClrImportant = 0; bmih.biClrUsed = 0; bmih.biCompression = BI_RGB; bmih.biHeight = height; bmih.biWidth = width; bmih.biPlanes = 1; bmih.biSizeImage = size; bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; BITMAPINFO bmpInfo; bmpInfo.bmiHeader = bmih; SetDIBits( hdc_tmp, bitmap, 0, height, buf, &bmpInfo, DIB_PAL_COLORS); SelectObject(hdc_tmp,bitmap); // save in the memory DC (double buffering) BitBlt( hdcBuf, x,y, width,height, hdc_tmp, 0,0, SRCCOPY); DeleteDC(hdc_tmp); DeleteObject(bitmap); } delete[] header; delete[] buf; }
static int GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { return -1; } UpdateYUVTextureData(texture); return 0; } else { GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; if (data->pixels) { Uint8 *src, *dst; int row; size_t length; src = (Uint8 *) pixels; dst = (Uint8 *) data->pixels + rect->y * data->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format); length = rect->w * SDL_BYTESPERPIXEL(texture->format); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += data->pitch; } if (data->premultiplied) { Uint32 *pixels = (Uint32 *) data->pixels + rect->y * (data->pitch / 4) + rect->x; switch (texture->format) { case SDL_PIXELFORMAT_ARGB8888: SDL_PreMultiplyAlphaARGB8888(rect->w, rect->h, pixels, data->pitch); break; case SDL_PIXELFORMAT_RGBA8888: SDL_PreMultiplyAlphaRGBA8888(rect->w, rect->h, pixels, data->pitch); break; case SDL_PIXELFORMAT_ABGR8888: SDL_PreMultiplyAlphaABGR8888(rect->w, rect->h, pixels, data->pitch); break; case SDL_PIXELFORMAT_BGRA8888: SDL_PreMultiplyAlphaBGRA8888(rect->w, rect->h, pixels, data->pitch); break; } } } else if (rect->w == texture->w && pitch == data->pitch) { #ifndef NO_GETDIBBITS if (!SetDIBits (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels, renderdata->bmi, DIB_RGB_COLORS)) { WIN_SetError("SetDIBits()"); return -1; } #else SDL_SetError("FIXME: Update Texture"); return -1; #endif } else { SDL_SetError ("FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time"); return -1; } return 0; } }
//---------------------------------------------------------------------------------------------------------- // This function draws Themes Tab control parts: a) Tab-Body and b) Tab-tabs void CXPTabCtrl::DrawThemesXpTabItem(CDC* pDC, int ixItem, const CRect& rcItem, UINT uiFlag) { // uiFlag(1/0):1=Type(body/tab);2=Sel(y/n);4=Hot(y/n);8=bBottom(y/n);16=rotate(y/n) BOOL bBody =(uiFlag& 1)?TRUE:FALSE; BOOL bSel =(uiFlag& 2)?TRUE:FALSE; BOOL bHot =(uiFlag& 4)?TRUE:FALSE; BOOL bBottom=(uiFlag& 8)?TRUE:FALSE; // mirror BOOL bVertic=(uiFlag&16)?TRUE:FALSE; // rotate BOOL bLeftTab=!bBottom && bVertic && !bBody; CSize szBmp=rcItem.Size(); if(bVertic) SwapVars(szBmp.cx,szBmp.cy); // 1st draw background CDC dcMem; dcMem .CreateCompatibleDC(pDC); CBitmap bmpMem; bmpMem.CreateCompatibleBitmap(pDC,szBmp.cx,szBmp.cy); CBitmap* pBmpOld=dcMem.SelectObject(&bmpMem); CRect rcMem(CPoint(0,0),szBmp); if(bSel) rcMem.bottom++; if(bBody) DrawThemesPart(dcMem.GetSafeHdc(), 9, 0, (LPCSTR)IDS_UTIL_TAB, &rcMem); // TABP_PANE=9, 0, 'TAB' else DrawThemesPart(dcMem.GetSafeHdc(), 1, bSel?3:(bHot?2:1), (LPCSTR)IDS_UTIL_TAB, &rcMem); // TABP_TABITEM=1, TIS_SELECTED=3:TIS_HOT=2:TIS_NORMAL=1, 'TAB' // 2nd init some extra parameters BITMAPINFO biOut; ZeroMemory(&biOut,sizeof(BITMAPINFO)); // Fill local pixel arrays BITMAPINFOHEADER& bihOut=biOut.bmiHeader; bihOut.biSize =sizeof (BITMAPINFOHEADER); bihOut.biCompression=BI_RGB; bihOut.biPlanes=1; bihOut.biBitCount=24; // force as RGB: 3 bytes,24 bits -> good for rotating bitmap in any resolution bihOut.biWidth =szBmp.cx; bihOut.biHeight=szBmp.cy; int nBmpWdtPS=DWordAlign(szBmp.cx*3); int nSzBuffPS=((nBmpWdtPS*szBmp.cy)/8+2)*8; LPBYTE pcImg=NULL; if(bBottom || bVertic) { pcImg=new BYTE[nSzBuffPS]; ASSERT(pcImg); } int nStart=0,nLenSub=0; if(bBody && bBottom && !bVertic) nStart=3,nLenSub=4; // if bottom oriented flip the body contest only (no shadows were flipped) // 3rd if it is left oriented tab, draw tab context before mirroring or rotating (before GetDIBits) if(bVertic) { if(bBody || !bBottom) bihOut.biHeight=-szBmp.cy; if(!bBottom && !bBody && ixItem>=0) // { if(bSel) rcMem.bottom--; DrawTabItem(&dcMem, ixItem, rcMem, uiFlag); ixItem=-1; } } // rotate or mirror // 4th get bits (for rotate) and mirror: body=(all except top) tab=(all except top) if(bVertic || bBottom) // get bits: { GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS); if(bBottom) // mirror: body=(bottom and right) tab=(bottom and right) { bihOut.biHeight=-szBmp.cy; // to mirror bitmap is eough to use negative height between Get/SetDIBits SetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS); if(bBody && bVertic) // when it is right oriented body -> flip twice, first flip border shadows, than flip shaded inside body again { nStart=2; nLenSub=4; bihOut.biHeight=szBmp.cy; GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS); bihOut.biHeight=-szBmp.cy; // to mirror bitmap is eough to use negative height between Get/SetDIBits SetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS); } } } // 5th if it is bottom or right oriented tab, draw after mirroring background (do GetDIBits again) if(!bBody && ixItem>=0) // { if(bSel) rcMem.bottom--; DrawTabItem(&dcMem, ixItem, rcMem, uiFlag); if(bVertic) // if it is right tab, do GetDIBits again { bihOut.biHeight=-szBmp.cy; GetDIBits(*pDC, bmpMem.operator HBITMAP(),nStart,szBmp.cy-nLenSub,pcImg,&biOut,DIB_RGB_COLORS); } } // 6th: do rotate now, finaly if(bVertic) // force rotating bitmap as RGB -> good for any resolution { SwapVars(szBmp.cx,szBmp.cy); int nBmpWdtPD=DWordAlign(szBmp.cx*3); int nPadD=nBmpWdtPD-szBmp.cx*3; int nSzBuffPD=((nBmpWdtPD*szBmp.cy)/8+2)*8; LPBYTE pcImgRotate=new BYTE[nSzBuffPD]; ASSERT(pcImgRotate); int nWidth,nHeight=szBmp.cy,nHeight1=nHeight-1; //==================================== //------------------------------------ // here is the example how to speed up lengthy repeatetive processing by using inline assembler #if !defined(_AMD64_) #define __USE_MASM__ // the same processing is in C and in asm. To use C -> comment the beginning of this line #endif // Do the actual whole RGB bitmap rotating in C or assembler #ifndef __USE_MASM__ LPBYTE pcImgS=pcImg; LPBYTE pcImgD=pcImgRotate; int ixHeight=0; BOOL bLast=FALSE; while(ixHeight<nHeight) // for all destination height lines { nWidth=szBmp.cx; if(ixHeight==nHeight1) { bLast=TRUE; nWidth--; } while(nWidth--) { *(PDWORD)pcImgD=*(PDWORD)pcImgS; // do all Rgb triplets read/write qicker as DWORD pcImgS+=nBmpWdtPS; // increment source in padded source lines pcImgD+=3; // increment destination in rgb triplets } if(bLast) // when the last line, the last pixel - colud be a problem if bitmap DWORD alligned for(int c=3;c;c--) *pcImgD++=*pcImgS++; // (only last three bytes available->could not read/write DWORD)!! else { ixHeight++; pcImgD+=nPadD; // destination bitmap horizontal padding to DWORD pcImgS=pcImg+(ixHeight*3); // reset the source to the begining of the next vertical line } } #else // __USE_MASM__ nBmpWdtPS-=4; // adjust esi increment (due to esi self-incrementing by movsd) nWidth=szBmp.cx; __asm { mov esi, pcImg // source index mov edi, pcImgRotate // destination index xor ebx, ebx // vertical counter loop_height: mov ecx, nWidth // horizontal counter cmp ebx, nHeight1 // check is it the last line jne loop_width dec ecx // if it is decremnt for the last pixel loop_width: movsd // copies 4 bytes and increments source and destination by 4 (we need only 3 bytes copied 'one pixel' RGB triplet) dec edi // adjust edi to 'as incremented by 3' add esi,nBmpWdtPS // adjust esi to the next source line loop loop_width // loop one hotizontal destination line cmp ebx, nHeight1 // check is it the last line je do_last // if not last, do incrementing here inc ebx // increment vertical counter add edi, nPadD // adjust destination index by possible padding to DWORD mov esi, ebx // reset the source index: add vertical counter * 3 shl esi, 1 // (is the same as * 2 +1*) add esi, ebx // +1* add esi, pcImg // add to the beginning of the source jmp loop_height // loop whole height do_last: // the last pixel is done by movsw // moving first two bytes movsb // and than by moving the very last byte } #endif // __USE_MASM__ dcMem.SelectObject(pBmpOld); bmpMem.DeleteObject(); // recreate rotated bitmap bmpMem.CreateCompatibleBitmap(pDC,szBmp.cx,szBmp.cy); dcMem.SelectObject(&bmpMem); bihOut.biWidth =szBmp.cx; bihOut.biHeight=bBody?-szBmp.cy:szBmp.cy; SetDIBits(*pDC, bmpMem.operator HBITMAP(),0,szBmp.cy,pcImgRotate,&biOut,DIB_RGB_COLORS); // set rotated bitmap bits delete pcImgRotate; } if(pcImg) delete pcImg; // 6th blit mirrored/rotated image to the screen pDC->BitBlt(rcItem.left,rcItem.top,szBmp.cx,szBmp.cy,&dcMem,0,0,SRCCOPY); // dcMem.SelectObject(pBmpOld); }
void GraphVizPreview::draw() { if (m_bmp_data.empty()) return; HWND pImage = GetDlgItem(m_hDlg, ID_PICTURE); { HWND pEdit = GetDlgItem(m_hDlg, IDC_GVP_EDIT); if (m_b_err) { const int offset = 40; SetWindowPos(m_hDlg, NULL, 0, 0, 600, 400, SWP_NOMOVE); SetWindowPos(pEdit, NULL, 0, 0, 600 - offset, 400 - offset, SWP_NOMOVE); m_bmp_data.push_back('\0'); SetWindowTextA(pEdit, &m_bmp_data[0]); ShowWindow(pEdit, SW_SHOWNORMAL); EnableWindow(pEdit, TRUE); ShowWindow(pImage, SW_HIDE); EnableWindow(pImage, FALSE); InvalidateRect(m_hDlg, NULL, TRUE); return; } else { SetWindowTextA(pEdit, ""); ShowWindow(pEdit, SW_HIDE); EnableWindow(pEdit, FALSE); ShowWindow(pImage, SW_SHOWNORMAL); EnableWindow(pImage, TRUE); } } HBITMAP hBmp; { char *pBuffer = &*m_bmp_data.begin(); tagBITMAPFILEHEADER bfh = *(tagBITMAPFILEHEADER*)pBuffer; tagBITMAPINFOHEADER bih = *(tagBITMAPINFOHEADER*)(pBuffer + sizeof(tagBITMAPFILEHEADER)); RGBQUAD rgb = *(RGBQUAD*)(pBuffer + sizeof(tagBITMAPFILEHEADER) + sizeof(tagBITMAPINFOHEADER)); BITMAPINFO bi; bi.bmiColors[0] = rgb; bi.bmiHeader = bih; char* pPixels = (pBuffer + bfh.bfOffBits); char* ppvBits = nullptr; hBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&ppvBits, NULL, 0); SetDIBits(NULL, hBmp, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS); } BITMAP bitmap; GetObject(hBmp, sizeof(bitmap), &bitmap); // Resize RECT dlg_dimensions, output_dimensions; GetClientRect(m_hDlg, &dlg_dimensions); // Maximize the draw area to the available area. SetWindowPos(pImage, NULL, 0, 0, dlg_dimensions.right, dlg_dimensions.bottom, SWP_NOMOVE | SWP_NOACTIVATE); // We will have to scale the bitmap, this section applies the scaling factor output_dimensions = dlg_dimensions; output_dimensions.right -= 1; output_dimensions.bottom -= 1; m_original_output_dimensions.top = 0; m_original_output_dimensions.left = 0; m_original_output_dimensions.right = bitmap.bmWidth; m_original_output_dimensions.bottom = bitmap.bmHeight; if (m_zoom <= 0.0) { double width_ratio = double(output_dimensions.right) / bitmap.bmWidth; double height_ratio = double(output_dimensions.bottom) / bitmap.bmHeight; if (width_ratio < 1.0 || height_ratio < 1.0) { if (width_ratio < height_ratio) { output_dimensions.right = static_cast<LONG>(bitmap.bmWidth * width_ratio); output_dimensions.bottom = static_cast<LONG>(bitmap.bmHeight * width_ratio); m_zoom = width_ratio; } else { output_dimensions.right = static_cast<LONG>(bitmap.bmWidth * height_ratio); output_dimensions.bottom = static_cast<LONG>(bitmap.bmHeight * height_ratio); m_zoom = height_ratio; } } else { output_dimensions.right = bitmap.bmWidth; output_dimensions.bottom = bitmap.bmHeight; m_zoom = 1.0; } } else { m_output_dimensions.right = static_cast<LONG>(m_output_dimensions.left + m_zoom * bitmap.bmWidth); m_output_dimensions.bottom = static_cast<LONG>(m_output_dimensions.top + m_zoom * bitmap.bmHeight); output_dimensions = m_output_dimensions; } m_output_dimensions = output_dimensions; // Begin painting PAINTSTRUCT ps; HDC hdc = BeginPaint(pImage, &ps); HDC hdcMem = CreateCompatibleDC(hdc); HGDIOBJ oldBitmap = SelectObject(hdcMem, hBmp); // Draw dark grey everywhere HBRUSH bg_color = CreateSolidBrush(RGB(200,200,200)); FillRect(hdc, &dlg_dimensions, bg_color); DeleteObject(bg_color); // Copy from bitmap to dialog rectangle, with scaling. StretchBlt(hdc, output_dimensions.left, output_dimensions.top, static_cast<LONG>(bitmap.bmWidth * m_zoom), static_cast<LONG>(bitmap.bmHeight * m_zoom), hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY); SelectObject(hdcMem, oldBitmap); DeleteDC(hdcMem); EndPaint(pImage, &ps); DeleteObject(hBmp); }
static BOOL ANIMATE_PaintFrame(ANIMATE_INFO* infoPtr, HDC hDC) { void const *pBitmapData; BITMAPINFO const *pBitmapInfo; HDC hdcMem; HBITMAP hbmOld; int nOffsetX = 0; int nOffsetY = 0; int nWidth; int nHeight; if (!hDC || !infoPtr->inbih) return TRUE; if (infoPtr->hic ) { pBitmapData = infoPtr->outdata; pBitmapInfo = (LPBITMAPINFO)infoPtr->outbih; nWidth = infoPtr->outbih->biWidth; nHeight = infoPtr->outbih->biHeight; } else { pBitmapData = infoPtr->indata; pBitmapInfo = (LPBITMAPINFO)infoPtr->inbih; nWidth = infoPtr->inbih->biWidth; nHeight = infoPtr->inbih->biHeight; } if(!infoPtr->hbmPrevFrame) { infoPtr->hbmPrevFrame=CreateCompatibleBitmap(hDC, nWidth,nHeight ); } hdcMem = CreateCompatibleDC(hDC); hbmOld = SelectObject(hdcMem, infoPtr->hbmPrevFrame); SetDIBits(hdcMem, infoPtr->hbmPrevFrame, 0, nHeight, pBitmapData, pBitmapInfo, DIB_RGB_COLORS); /* * we need to get the transparent color even without ACS_TRANSPARENT, * because the style can be changed later on and the color should always * be obtained in the first frame */ if(infoPtr->transparentColor == ANIMATE_COLOR_NONE) { infoPtr->transparentColor = GetPixel(hdcMem,0,0); } if(infoPtr->dwStyle & ACS_TRANSPARENT) { HDC hdcFinal = CreateCompatibleDC(hDC); HBITMAP hbmFinal = CreateCompatibleBitmap(hDC,nWidth, nHeight); HBITMAP hbmOld2 = SelectObject(hdcFinal, hbmFinal); RECT rect; rect.left = 0; rect.top = 0; rect.right = nWidth; rect.bottom = nHeight; if(!infoPtr->hbrushBG) infoPtr->hbrushBG = GetCurrentObject(hDC, OBJ_BRUSH); FillRect(hdcFinal, &rect, infoPtr->hbrushBG); ANIMATE_TransparentBlt(infoPtr, hdcFinal, hdcMem); SelectObject(hdcFinal, hbmOld2); SelectObject(hdcMem, hbmFinal); DeleteDC(hdcFinal); DeleteObject(infoPtr->hbmPrevFrame); infoPtr->hbmPrevFrame = hbmFinal; } if (infoPtr->dwStyle & ACS_CENTER) { RECT rect; GetWindowRect(infoPtr->hwndSelf, &rect); nOffsetX = ((rect.right - rect.left) - nWidth)/2; nOffsetY = ((rect.bottom - rect.top) - nHeight)/2; } BitBlt(hDC, nOffsetX, nOffsetY, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); return TRUE; }
/***************************************************************************** * SIC_OverlayShortcutImage [internal] * * NOTES * Creates a new icon as a copy of the passed-in icon, overlayed with a * shortcut image. * FIXME: This should go to the ImageList implementation! */ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) { ICONINFO ShortcutIconInfo, TargetIconInfo; HICON ShortcutIcon = NULL, TargetIcon; BITMAP TargetBitmapInfo, ShortcutBitmapInfo; HDC ShortcutDC = NULL, TargetDC = NULL; HBITMAP OldShortcutBitmap = NULL, OldTargetBitmap = NULL; static int s_imgListIdx = -1; ZeroMemory(&ShortcutIconInfo, sizeof(ShortcutIconInfo)); ZeroMemory(&TargetIconInfo, sizeof(TargetIconInfo)); /* Get information about the source icon and shortcut overlay. * We will write over the source bitmaps to get the final ones */ if (! GetIconInfo(SourceIcon, &TargetIconInfo)) return NULL; /* Is it possible with the ImageList implementation? */ if(!TargetIconInfo.hbmColor) { /* Maybe we'll support this at some point */ FIXME("1bpp icon wants its overlay!\n"); goto fail; } if(!GetObjectW(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo)) { goto fail; } /* search for the shortcut icon only once */ if (s_imgListIdx == -1) s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT); /* FIXME should use icon index 29 instead of the resource id, but not all icons are present yet so we can't use icon indices */ if (s_imgListIdx != -1) { if (large) ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT); else ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); } else ShortcutIcon = NULL; if (!ShortcutIcon || !GetIconInfo(ShortcutIcon, &ShortcutIconInfo)) { goto fail; } /* Is it possible with the ImageLists ? */ if(!ShortcutIconInfo.hbmColor) { /* Maybe we'll support this at some point */ FIXME("Should draw 1bpp overlay!\n"); goto fail; } if(!GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo)) { goto fail; } /* Setup the masks */ ShortcutDC = CreateCompatibleDC(NULL); if (NULL == ShortcutDC) goto fail; OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask); if (NULL == OldShortcutBitmap) goto fail; TargetDC = CreateCompatibleDC(NULL); if (NULL == TargetDC) goto fail; OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask); if (NULL == OldTargetBitmap) goto fail; /* Create the complete mask by ANDing the source and shortcut masks. * NOTE: in an ImageList, all icons have the same dimensions */ if (!BitBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight, ShortcutDC, 0, 0, SRCAND)) { goto fail; } /* * We must remove or add the alpha component to the shortcut overlay: * If we don't, SRCCOPY will copy it to our resulting icon, resulting in a * partially transparent icons where it shouldn't be, and to an invisible icon * if the underlying icon don't have any alpha channel information. (16bpp only icon for instance). * But if the underlying icon has alpha channel information, then we must mark the overlay information * as opaque. * NOTE: This code sucks(tm) and should belong to the ImageList implementation. * NOTE2: there are better ways to do this. */ if(ShortcutBitmapInfo.bmBitsPixel == 32) { BOOL add_alpha; BYTE buffer[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; PVOID bits; PULONG pixel; INT i, j; /* Find if the source bitmap has an alpha channel */ if(TargetBitmapInfo.bmBitsPixel != 32) add_alpha = FALSE; else { ZeroMemory(buffer, sizeof(buffer)); lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbmi->bmiHeader.biWidth = TargetBitmapInfo.bmWidth; lpbmi->bmiHeader.biHeight = TargetBitmapInfo.bmHeight; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiHeader.biBitCount = 32; bits = HeapAlloc(GetProcessHeap(), 0, TargetBitmapInfo.bmHeight * TargetBitmapInfo.bmWidthBytes); if(!bits) goto fail; if(!GetDIBits(TargetDC, TargetIconInfo.hbmColor, 0, TargetBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS)) { ERR("GetBIBits failed!\n"); HeapFree(GetProcessHeap(), 0, bits); goto fail; } i = j = 0; pixel = (PULONG)bits; for(i=0; i<TargetBitmapInfo.bmHeight; i++) { for(j=0; j<TargetBitmapInfo.bmWidth; j++) { add_alpha = (*pixel++ & 0xFF000000) != 0; if(add_alpha) break; } if(add_alpha) break; } HeapFree(GetProcessHeap(), 0, bits); } /* Allocate the bits */ bits = HeapAlloc(GetProcessHeap(), 0, ShortcutBitmapInfo.bmHeight*ShortcutBitmapInfo.bmWidthBytes); if(!bits) goto fail; ZeroMemory(buffer, sizeof(buffer)); lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbmi->bmiHeader.biWidth = ShortcutBitmapInfo.bmWidth; lpbmi->bmiHeader.biHeight = ShortcutBitmapInfo.bmHeight; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiHeader.biBitCount = 32; if(!GetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS)) { ERR("GetBIBits failed!\n"); HeapFree(GetProcessHeap(), 0, bits); goto fail; } pixel = (PULONG)bits; /* Remove alpha channel component or make it totally opaque */ for(i=0; i<ShortcutBitmapInfo.bmHeight; i++) { for(j=0; j<ShortcutBitmapInfo.bmWidth; j++) { if(add_alpha) *pixel++ |= 0xFF000000; else *pixel++ &= 0x00FFFFFF; } } /* GetDIBits return BI_BITFIELDS with masks set to 0, and SetDIBits fails when masks are 0. The irony... */ lpbmi->bmiHeader.biCompression = BI_RGB; /* Set the bits again */ if(!SetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS)) { ERR("SetBIBits failed!, %lu\n", GetLastError()); HeapFree(GetProcessHeap(), 0, bits); goto fail; } HeapFree(GetProcessHeap(), 0, bits); } /* Now do the copy. We overwrite the original icon data */ if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor) || NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor)) goto fail; if (!MaskBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight, ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0, MAKEROP4(0xAA0000, SRCCOPY))) { goto fail; } /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set handles to NULL */ SelectObject(TargetDC, OldTargetBitmap); DeleteDC(TargetDC); SelectObject(ShortcutDC, OldShortcutBitmap); DeleteDC(ShortcutDC); /* Create the icon using the bitmaps prepared earlier */ TargetIcon = CreateIconIndirect(&TargetIconInfo); /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */ DeleteObject(TargetIconInfo.hbmColor); DeleteObject(TargetIconInfo.hbmMask); /* Delete what GetIconInfo gave us */ DeleteObject(ShortcutIconInfo.hbmColor); DeleteObject(ShortcutIconInfo.hbmMask); DestroyIcon(ShortcutIcon); return TargetIcon; fail: /* Clean up scratch resources we created */ if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap); if (NULL != TargetDC) DeleteDC(TargetDC); if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap); if (NULL != ShortcutDC) DeleteDC(ShortcutDC); if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor); if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask); if (NULL != ShortcutIconInfo.hbmColor) DeleteObject(ShortcutIconInfo.hbmColor); if (NULL != ShortcutIconInfo.hbmMask) DeleteObject(ShortcutIconInfo.hbmMask); if (NULL != ShortcutIcon) DestroyIcon(ShortcutIcon); return NULL; }
///////////////////////////////////////////////////////////////////////////////////////////////// // Method name : DisplaySharpness // Arguments : // 1) HDC hMemDC -- Device context // 2) RECT &r -- Rectangle position // Return type : void // Formula : (C1*5) - (C2+C3+C4+C5) // Precondition : 1)gdiplus should be intialize // Postcondition: None ///////////////////////////////////////////////////////////////////////////////////////////////// void CImageProcess::DisplaySharpness(HDC hMemDC, RECT &r) { BITMAPINFO bi; BOOL bRes; char *pOriBuf; // Original buffer // Bitmap header bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = m_nWidth; bi.bmiHeader.biHeight = m_nHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = m_nWidth * 4 * m_nHeight; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; pOriBuf = (char *) malloc(m_nWidth * 4 * m_nHeight); char *tmpBuf = (char *) malloc(m_nWidth * 4 * m_nHeight); bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, pOriBuf, &bi, DIB_RGB_COLORS); long nCount=0; long c1, c2, c3, c4, c5; // Retrive from original buffer // Caluculate the value and store new value into tmpBuf for (int i=0; i<m_nHeight; ++i) { for (int j=0; j<m_nWidth; ++j) { long lVal=0; memcpy(&lVal, &pOriBuf[nCount], 4); int b = GetRValue(lVal); int g = GetGValue(lVal); int r = GetBValue(lVal); c1 = r; // Red if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4))) { memcpy(&lVal, &pOriBuf[nCount-(m_nWidth*4l)], 4); c2 = GetBValue(lVal); memcpy(&lVal, &pOriBuf[nCount+4], 4); c3 = GetBValue(lVal); memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4); c4 = GetBValue(lVal); memcpy(&lVal, &pOriBuf[nCount-4], 4); c5 = GetBValue(lVal); r = (c1*5) - (c2+c3+c4+c5); } // Green c1 = g; if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4))) { memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4); c2 = GetGValue(lVal); memcpy(&lVal, &pOriBuf[nCount+4], 4); c3 = GetGValue(lVal); memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4); c4 = GetGValue(lVal); memcpy(&lVal, &pOriBuf[nCount-4], 4); c5 = GetGValue(lVal); g = (c1*5) - (c2+c3+c4+c5); } // Blue c1 = b; if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4))) { memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4); c2 = GetRValue(lVal); memcpy(&lVal, &pOriBuf[nCount+4], 4); c3 = GetRValue(lVal); memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4); c4 = GetRValue(lVal); memcpy(&lVal, &pOriBuf[nCount-4], 4); c5 = GetRValue(lVal); b = (c1*5) - (c2+c3+c4+c5); } // Red if (r >255) { r = 255; } if (r <0) { r = 0; } // Green if (g>255) { g = 255; } if (g<0) { g = 0; } // Blue if (b >255) { b = 255; } if (b<0) { b = 0; } // Store in reverse order lVal = RGB(b, g, r); memcpy(&tmpBuf[nCount], &lVal, 4); nCount+=4; } } // Store tmpBuf SetDIBits(hMemDC, m_hBitmap, 0, bRes, tmpBuf, &bi, DIB_RGB_COLORS); free(pOriBuf); free(tmpBuf); RECT tmpRect = r; tmpRect.right += 16; tmpRect.bottom+= 16; InvalidateRect(GetActiveWindow(), &tmpRect, FALSE); }
void keyPressed(int vk){ switch (vk){ case VK_ESCAPE: if (hbitmap != NULL){ if (selectRect.valid){ selectRect.valid = false; } else{ DeleteObject(hbitmap); hbitmap = NULL; selectRect.valid = false; delete[] capturePixels; DeleteObject(buffer); ShowWindow(hwnd, SW_HIDE); } } break; case VK_RETURN: sendToClipboard(); disposeWindow(); break; case 'C': if (ctrlPressed) sendToClipboard(); break; case 'X': if (ctrlPressed){ sendToClipboard(); disposeWindow(); } break; case 'S': if (ctrlPressed){ OPENFILENAMEW openFile = { 0 }; wchar_t filePath[261]; memset(&filePath, 0, 261); openFile.lStructSize = sizeof(OPENFILENAMEA); openFile.hwndOwner = hwnd; openFile.lpstrFile = filePath; openFile.nMaxFile = 261; openFile.Flags = OFN_EXPLORER; unsigned int num = 0, size = 0; GetImageEncodersSize(&num, &size); ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size)); GetImageEncoders(num, size, pImageCodecInfo); wstring s; DWORD index = 0; for (unsigned int i = 0; i < num; ++i){ const wchar_t *format = pImageCodecInfo[i].FormatDescription; const wchar_t *filename = pImageCodecInfo[i].FilenameExtension; wstring fileLower(filename); transform(fileLower.begin(), fileLower.end(), fileLower.begin(), tolower); s = s + wstring(format, wcslen(format)) + wstring(L" (") + fileLower + wstring(L")", 2) + wstring(filename, wcslen(filename) + 1); if (wcscmp(format, L"PNG") == 0) { index = i + 1; } } s = s + wstring(L"\0", 1); openFile.lpstrFilter = s.c_str(); openFile.lpstrCustomFilter = NULL; openFile.lpstrFileTitle = NULL; openFile.lpstrInitialDir = NULL; openFile.lpstrTitle = L"Save Capture As"; openFile.nFilterIndex = index; if (!GetSaveFileNameW(&openFile)){ return; } BITMAPINFOHEADER bmih; bmih.biSize = sizeof(BITMAPINFOHEADER); bmih.biWidth = selectRect.width; bmih.biHeight = -selectRect.height; bmih.biPlanes = 1; bmih.biBitCount = 32; bmih.biCompression = BI_RGB; BITMAPINFO dbmi; dbmi.bmiHeader = bmih; HDC hdc = GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP capture = CreateCompatibleBitmap(hdc, selectRect.width, selectRect.height); bufferWidth = rect.right - rect.left; bufferHeight = rect.bottom - rect.top; pixel *ps = new pixel[selectRect.width * selectRect.height]; HGDIOBJ old = SelectObject(hdcMem, hbitmap); for (int i = 0; i < selectRect.height; i++){ memcpy(&ps[i * selectRect.width], &capturePixels[(i + selectRect.y) * bufferWidth + selectRect.x], selectRect.width * 4); } SetDIBits(hdc, capture, 0, selectRect.height, ps, &dbmi, 0); ImageCodecInfo info = pImageCodecInfo[openFile.nFilterIndex - 1]; wchar_t *fne = new wchar_t[wcslen(info.FilenameExtension) + 1]; wcscpy_s(fne, wcslen(info.FilenameExtension) + 1, info.FilenameExtension); wchar_t *context = NULL; wchar_t *c = wcstok_s(fne, L";", &context); wchar_t *first = c; bool found = false; while (c != NULL){ wstring str(filePath); transform(str.begin(), str.end(), str.begin(), toupper); wstring suffix(c); suffix = suffix.substr(1); if (str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0){ found = true; } c = wcstok_s(NULL, L";", &context); } wstring path(filePath); if (!found){ wstring extension = wstring(first).substr(1); transform(extension.begin(), extension.end(), extension.begin(), tolower); path = path + extension; } Bitmap bitmap(capture, NULL); bitmap.Save(path.c_str(), &(info.Clsid)); delete[] fne; SelectObject(hdc, old); ReleaseDC(NULL, hdc); DeleteDC(hdcMem); DeleteObject(capture); delete[] ps; delete[] pImageCodecInfo; } break; } }
///////////////////////////////////////////////////////////////////////////////////////////////// // Method name : DisplayBrightness // Arguments : // 1) HDC hMemDC -- Device context // 2) RECT &r -- Rectangle position // 3) int nRedVal -- Red color Value. If it have +ve, it's going to Dark RED. // If it's -ve , it's going to Light RED // 4) int nGreenVal-- Green color Value. If it have +ve, it's going to Dark Green . // If it's -ve , it's going to Light Green // 5) int nBlueVal -- Blue color Value. If it have +ve, it's going to Dark Blue. // If it's -ve , it's going to Light Blue // These Red,Green,Blue value between -255 to 255 // Return type : void // Description : Brightness have 2 types. 1) Dark 2) light. // Formula : Color = Color + nColorVal; (ex) Red = Red + nRedVal; Blue = Blue + nBlueVal // Precondition : 1)gdiplus should be intialize 2) Image should be load // Postcondition: None ///////////////////////////////////////////////////////////////////////////////////////////////// void CImageProcess::DisplayBrightness(HDC hMemDC, RECT &r, int nRedVal, int nGreenVal, int nBlueVal) { BITMAPINFO bi; BOOL bRes; char *buf; // Bitmap header bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = m_nWidth; bi.bmiHeader.biHeight = m_nHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = m_nWidth * 4 * m_nHeight; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; // Buffer buf = (char *) malloc(m_nWidth * 4 * m_nHeight); // Don't use getPixel and SetPixel.It's very slow. // Get the all scanline. bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, buf, &bi, DIB_RGB_COLORS); long nCount=0; for (int i=0; i<m_nHeight; ++i) { for (int j=0; j<m_nWidth; ++j) { long lVal=0; memcpy(&lVal, &buf[nCount], 4); // Get the reverse order int b = GetRValue(lVal); int g = GetGValue(lVal); int r = GetBValue(lVal); // Red r += nRedVal; if (r >255) { r = 255; } if (r <0) { r = 0; } // Green g += nGreenVal; if (g>255) { g = 255; } if (g<0) { g = 0; } // Blue b += nBlueVal; if (b >255) { b = 255; } if (b<0) { b = 0; } // Store reverse order lVal = RGB(b, g, r); memcpy(&buf[nCount], &lVal, 4); // Increment with 4. RGB color take 4 bytes.The high-order byte must be zero // See in MSDN COLORREF nCount+=4; } } // Set again SetDIBits(hMemDC, m_hBitmap, 0, bRes, buf, &bi, DIB_RGB_COLORS); free(buf); RECT tmpRect = r; tmpRect.right += 16; tmpRect.bottom += 16; InvalidateRect(GetActiveWindow(), &tmpRect, FALSE); }
///////////////////////////////////////////////////////////////////////////////////////////////// // Method name : DisplayContrast // Arguments : // 1) HDC hMemDC -- Device context // 2) RECT &r -- Rectangle position // 3) int nContrastVal -- Contrast value(Value between 0 to 200) // Return type : void // Description : It have 2 type. 1) Low contrast 2) High contrast // Formula : Color = ((Color-128)*nContrastVal)/100 +128; // Precondition : 1)gdiplus should be intialize 2) Image should be load // Postcondition: ///////////////////////////////////////////////////////////////////////////////////////////////// void CImageProcess::DisplayContrast(HDC hMemDC, RECT &r, int nContrastVal) { BITMAPINFO bi; BOOL bRes; char *buf; // Bitmap header bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = m_nWidth; bi.bmiHeader.biHeight = m_nHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = m_nWidth * 4 * m_nHeight; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; buf = (char *) malloc(m_nWidth * 4 * m_nHeight); bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, buf, &bi, DIB_RGB_COLORS); long nCount=0; for (int i=0; i<m_nHeight; ++i) { for (int j=0; j<m_nWidth; ++j) { long lVal=0; memcpy(&lVal, &buf[nCount], 4); // Get from buffer in reverse order int b = GetRValue(lVal); int g = GetGValue(lVal); int r = GetBValue(lVal); r = ((r-128)*nContrastVal)/100 +128; g = ((g-128)*nContrastVal)/100 +128; b = ((b-128)*nContrastVal)/100 +128; // Red if (r >255) { r = 255; } if (r <0) { r = 0; } // Green if (g>255) { g = 255; } if (g<0) { g = 0; } // Blue if (b >255) { b = 255; } if (b<0) { b = 0; } // Store in reverse order lVal = RGB((int)b, (int)g, (int)r); memcpy(&buf[nCount], &lVal, 4); nCount+=4; } } SetDIBits(hMemDC, m_hBitmap, 0, bRes, buf, &bi, DIB_RGB_COLORS); free(buf); RECT tmpRect = r; tmpRect.right += 16; tmpRect.bottom += 16; InvalidateRect(GetActiveWindow(), &tmpRect, FALSE); }
void eFont::create(const eChar *fontFace, const eChar *letters, eU32 height, eColor color) { LOGFONT lf; eMemSet(&lf, 0, sizeof(lf)); eStrCopy(lf.lfFaceName, fontFace); lf.lfHeight = -(eInt)height; lf.lfWeight = FW_NORMAL; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_TT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = ANTIALIASED_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; HFONT font = CreateFontIndirect(&lf); eASSERT(font); HDC hdc = GetDC(nullptr); eASSERT(hdc); HDC compDc = CreateCompatibleDC(hdc); eASSERT(compDc); SetTextColor(compDc, RGB(color.b, color.g, color.r)); SetBkMode(compDc,TRANSPARENT); SelectObject(compDc, font); TEXTMETRIC met; GetTextMetrics(compDc, &met); m_height = met.tmHeight; const eU32 border = 2; const eU32 numLetters = eStrLength(letters); const eF32 chrPerLine = eSqrt((eF32)numLetters); const eU32 texWidth = eNextPowerOf2(eFtoL((eF32)(met.tmAveCharWidth+border)*chrPerLine)); const eU32 texHeight = eNextPowerOf2(eFtoL((eF32)(met.tmHeight+border)*chrPerLine)); HBITMAP bmp = CreateCompatibleBitmap(hdc, texWidth, texHeight); eASSERT(bmp); SelectObject(compDc, bmp); m_bmp.resize(texWidth*texHeight); eMemSet(&m_bmp[0], 0, m_bmp.size()*sizeof(eColor)); BITMAPINFO bmi; eMemSet(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = texWidth; bmi.bmiHeader.biHeight = -(eInt)texHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; SetDIBits(compDc, bmp, 0, texHeight, &m_bmp[0],&bmi,DIB_RGB_COLORS); eU32 x = 0; eU32 y = 0; for (eU32 i=0; i<numLetters; i++) { const eChar c = letters[i]; const eChar text[] = {c, '\0'}; SIZE size; GetTextExtentPoint32(compDc, text, 1, &size); if (x+size.cx >= texWidth) { x = 0; y += met.tmHeight+border; } eFontLetter &l = m_letters[c]; l.chr = c; l.width = size.cx; l.used = eTRUE; l.rect.set(x, y, x+l.width, y+met.tmHeight); l.uv.set((eF32)x/(eF32)texWidth, (eF32)y/(eF32)texHeight); ExtTextOut(compDc, x, y, 0, nullptr, text, 1, nullptr); x += l.width+border; } GetDIBits(compDc,bmp, 0, texHeight, &m_bmp[0], &bmi, DIB_RGB_COLORS); DeleteObject(font); DeleteObject(bmp); DeleteDC(compDc); DeleteDC(hdc); for (eU32 i=0; i<m_bmp.size(); i++) m_bmp[i].a = 255; if (!m_tex || m_tex->width != texWidth || m_tex->height != texHeight) { eGfx->removeTexture2d(m_tex); m_tex = eGfx->addTexture2d(texWidth, texHeight, eTEX_NOMIPMAPS, eTFO_ARGB8); } eGfx->updateTexture2d(m_tex, &m_bmp[0]); }
BOOL CImage::LoadBitmapFromJPEGFile(LPTSTR szFileName) { BOOL bStatus = false; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; FILE* fp = NULL; JSAMPROW row = NULL; BITMAPINFO bmi; HDC hDC = NULL; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); _TFOPEN_S(fp, szFileName, _T("rb")); if (!fp) { goto cleanup; } jpeg_stdio_src(&cinfo, fp); jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); row = new BYTE[cinfo.output_width*3+10]; hDC = GetDC(NULL); { CAutoLock lock(&m_csLock); if(m_bLoadCancelled) goto cleanup; m_hBitmap = CreateCompatibleBitmap(hDC, cinfo.output_width, cinfo.output_height); } memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(bmi); bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biWidth = cinfo.output_width; bmi.bmiHeader.biHeight = cinfo.output_height; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = cinfo.output_width*cinfo.output_height*3; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &row, 1); if(cinfo.out_color_components==3) { // Convert RGB to BGR UINT i; for(i=0; i<cinfo.output_width; i++) { BYTE tmp = row[i*3+0]; row[i*3+0] = row[i*3+2]; row[i*3+2] = tmp; } } else { // Convert grayscale to BGR int i; for(i=cinfo.output_width-1; i>=0; i--) { row[i*3+0] = row[i]; row[i*3+1] = row[i]; row[i*3+2] = row[i]; } } { CAutoLock lock(&m_csLock); int n = SetDIBits(hDC, m_hBitmap, cinfo.output_height-cinfo.output_scanline, 1, row, &bmi, DIB_RGB_COLORS); if(n==0) goto cleanup; } } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); bStatus = true; cleanup: if(row) delete [] row; if(!bStatus) { Destroy(); } if(fp!=NULL) { fclose(fp); fp = NULL; } return bStatus; }
BOOL CImage::LoadBitmapFromPNGFile(LPTSTR szFileName) { BOOL bStatus = FALSE; FILE *fp = NULL; const int number = 8; png_byte header[number]; png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_infop end_info = NULL; png_uint_32 rowbytes = 0; png_uint_32 width = 0; png_uint_32 height = 0; png_bytep row = NULL; int y = 0; BITMAPINFO* pBMI = NULL; HDC hDC = NULL; _TFOPEN_S(fp, szFileName, _T("rb")); if (!fp) { return FALSE; } fread(header, 1, number, fp); if(png_sig_cmp(header, 0, number)) { goto cleanup; } png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) goto cleanup; if (setjmp(png_ptr->jmpbuf)) goto cleanup; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) goto cleanup; end_info = png_create_info_struct(png_ptr); if (!end_info) goto cleanup; png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, number); // Read PNG information png_read_info(png_ptr, info_ptr); // Get count of bytes per row rowbytes = png_get_rowbytes(png_ptr, info_ptr); row = new png_byte[rowbytes]; width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); if(info_ptr->channels==3) { png_set_strip_16(png_ptr); png_set_packing(png_ptr); png_set_bgr(png_ptr); } hDC = GetDC(NULL); { CAutoLock lock(&m_csLock); if(m_bLoadCancelled) goto cleanup; m_hBitmap = CreateCompatibleBitmap(hDC, width, height); } pBMI = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)+256*4]; memset(pBMI, 0, sizeof(BITMAPINFO)+256*4); pBMI->bmiHeader.biSize = sizeof(BITMAPINFO); pBMI->bmiHeader.biBitCount = 8*info_ptr->channels; pBMI->bmiHeader.biWidth = width; pBMI->bmiHeader.biHeight = height; pBMI->bmiHeader.biPlanes = 1; pBMI->bmiHeader.biCompression = BI_RGB; pBMI->bmiHeader.biSizeImage = rowbytes*height; if( info_ptr->channels == 1 ) { RGBQUAD* palette = pBMI->bmiColors; int i; for( i = 0; i < 256; i++ ) { palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; palette[i].rgbReserved = 0; } palette[256].rgbBlue = palette[256].rgbGreen = palette[256].rgbRed = 255; } for(y=height-1; y>=0; y--) { png_read_rows(png_ptr, &row, png_bytepp_NULL, 1); { CAutoLock lock(&m_csLock); int n = SetDIBits(hDC, m_hBitmap, y, 1, row, pBMI, DIB_RGB_COLORS); if(n==0) goto cleanup; } } /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); bStatus = TRUE; cleanup: if(fp!=NULL) { fclose(fp); } if(png_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)&info_ptr, (png_infopp)&end_info); } if(row) { delete [] row; } if(pBMI) { delete [] pBMI; } if(!bStatus) { Destroy(); } return bStatus; }
ALERROR dibLoadFromBlock (IReadBlock &Data, HBITMAP *rethDIB, EBitmapTypes *retiType) // dibLoadFromBlock // // Loads a DIB into memory { ALERROR error; HBITMAP hDIB; HANDLE hFileData; int iBitsOffset; BITMAPINFOHEADER bi; if (error = Data.Open()) return error; // Get information if (error = ReadDIBInfo(&Data, &hFileData, &iBitsOffset, &bi)) return error; // Return the bit-depth of the original bitmap if (retiType) { switch (bi.biBitCount) { case 1: *retiType = bitmapMonochrome; break; case 8: *retiType = bitmapAlpha; break; default: *retiType = bitmapRGB; break; } } // Calculate how much space we need for the bits DWORD dwBits = bi.biSizeImage; DWORD dwPaletteSize = dibPaletteSize(&bi); DWORD dwLen = bi.biSize + dwPaletteSize + dwBits; // Create a DIBSection if (error = dibCreate16bitDIB(bi.biWidth, bi.biHeight, &hDIB, NULL)) { GlobalFree(hFileData); return error; } // Set the bits HDC hDC = CreateCompatibleDC(NULL); SetDIBits(hDC, hDIB, 0, bi.biHeight, Data.GetPointer(iBitsOffset, -1), (BITMAPINFO *)GlobalLock(hFileData), DIB_RGB_COLORS); ::DeleteDC(hDC); GlobalUnlock(hFileData); GlobalFree(hFileData); // Done *rethDIB = hDIB; return NOERROR; }
BOOL CDrawMandelbrotDlg::Draw() { CRect rect; GetWindowRect(&rect); int width = rect.Width(); int height = rect.Height(); m_top = m_bottom + (m_right - m_left) * height / width; CClientDC dc(this); CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, width, height); memDC.SelectObject(&bmp); BITMAPINFO bmpInfo; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = width; bmpInfo.bmiHeader.biHeight = -height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 3000; bmpInfo.bmiHeader.biYPelsPerMeter = 3000; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; long bytesPerLine = (bmpInfo.bmiHeader.biWidth * 3 + 3) / 4 * 4; long bufferSize = bytesPerLine * height; BYTE *buffer = new BYTE[bufferSize]; memset(buffer, 0, bufferSize); int maxLoop = 1500; double w = m_right - m_left; double h = m_top - m_bottom; int iTmp = -1; int index = -1; #pragma omp parallel for for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { ComplexNum z; ComplexNum c; double dTmp; int loopCount = 0; c.real = w * (i + 1) / width + m_left; c.imag = h * (j + 1) / height + m_bottom; do { dTmp = z.real * z.real - z.imag * z.imag + c.real; z.imag = 2 * z.real * z.imag + c.imag; z.real = dTmp; ++loopCount; } while((z.real * z.real + z.imag * z.imag) < 4 && loopCount < maxLoop); if (loopCount != maxLoop) { int iTmp = loopCount % 255; index = j * bytesPerLine + i * 3; buffer[index] = iTmp; buffer[index + 1] = iTmp * 5; buffer[index + 2] = iTmp * 10; } } } SetDIBits(dc.m_hDC, bmp, 0, height, buffer, &bmpInfo, DIB_RGB_COLORS); delete []buffer; dc.BitBlt(0, 0, bmpInfo.bmiHeader.biWidth, height, &memDC, 0, 0, SRCCOPY); return true; }