/* * test for gdi+ */ #include "hdr/modern_commonheaders.h" #undef Translate //otherwise will conflict with gdi plus Translate #include #include "hdr/modern_global_structure.h" BYTE saved_alpha; ULONG_PTR g_gdiplusToken; int mir_strlen(const char *a); HBITMAP ske_CreateDIB32(int cx, int cy); void InitGdiPlus(void) { Gdiplus::GdiplusStartupInput gdiplusStartupInput; g_CluiData.fGDIPlusFail = false; __try { if (g_gdiplusToken == 0) Gdiplus::GdiplusStartup(&g_gdiplusToken, &gdiplusStartupInput, NULL); } __except ( EXCEPTION_EXECUTE_HANDLER ) { g_CluiData.fGDIPlusFail = true; } } void ShutdownGdiPlus(void) { Gdiplus::GdiplusStartupInput gdiplusStartupInput; __try { if (g_gdiplusToken) Gdiplus::GdiplusShutdown(g_gdiplusToken); } __except ( EXCEPTION_EXECUTE_HANDLER ) { g_CluiData.fGDIPlusFail = true; } g_gdiplusToken = 0; } using namespace Gdiplus; static ColorMatrix ClrMatrix = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; int g_hottrack; DWORD argb_from_cola(COLORREF col, BYTE alpha) { return((BYTE) (alpha) << 24 | col); } HBITMAP GDIPlus_LoadGlyphImage(char *szFileName) { WCHAR *string; string = (WCHAR*)malloc(sizeof(WCHAR)*(mir_strlen(szFileName)+2)); MultiByteToWideChar(CP_ACP, 0, szFileName, -1, string, (mir_strlen(szFileName)+2)*sizeof(WCHAR)); // Create a Bitmap object from a JPEG file. Bitmap bitmap(string,0); free(string); // Clone a portion of the bitmap. Bitmap* clone = bitmap.Clone(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), PixelFormat32bppPARGB); HBITMAP hbmp = NULL; if (clone) { clone->GetHBITMAP(Color(0,0,0),&hbmp); delete clone; } return hbmp; } void TextOutWithGDIp(HDC hDestDC, int x, int y, LPCTSTR lpString, int nCount) { // Graphics s(hDestDC); // HBITMAP hs; // hs = (HBITMAP)GetCurrentObject(hDestDC,OBJ_BITMAP); // Bitmap sb(hs,NULL); // Bitmap *b = (sb.Clone(x,y,150,30,PixelFormat32bppARGB)); // Graphics g(b);//(100,100,PixelFormat32bppPARGB); // //g.DrawImage(sb); // // s.SetCompositingMode(CompositingModeSourceCopy); // // g.SetCompositingMode(CompositingModeSourceCopy); // g.DrawImage(&sb,0,0,x,y,100,30,UnitPixel); // //s.SetCompositingMode(CompositingModeSourceCopy); // //g.SetCompositingMode(CompositingModeSourceCopy); // // Create a string. // // WCHAR *string; // string = (WCHAR*)malloc(sizeof(WCHAR)*(nCount+2)); // MultiByteToWideChar(CP_ACP, 0, lpString, -1, string, (nCount+2)*sizeof(WCHAR)); // Font myFont(hDestDC); // // PointF origin((float)0, (float)0); // PointF origin2((float)x, (float)y); // g.SetTextRenderingHint(TextRenderingHintSystemDefault); // g.SetSmoothingMode(SmoothingModeAntiAlias); // COLORREF ref = GetTextColor(hDestDC); // SolidBrush blackBrush(Color(255, GetRValue(ref),GetGValue(ref),GetBValue(ref))); // g.SetInterpolationMode(InterpolationModeHighQualityBicubic); // g.DrawString(string,nCount,&myFont,origin, &blackBrush); // //g.SetCompositingMode(CompositingModeSourceCopy); // //s.SetCompositingMode(CompositingModeSourceCopy); // free(string); // //HDC temp = g.GetHDC(); // //BitBlt(hDestDC,x,y,100,100,temp,0,0,SRCCOPY); // //g.ReleaseHDC(temp); // s.DrawImage(b,origin2); // } void DrawAvatarImageWithGDIp(HDC hDestDC,int x, int y, DWORD width, DWORD height, HBITMAP hbmp, int x1, int y1, DWORD width1, DWORD height1,DWORD flag,BYTE alpha) { BITMAP bmp; Bitmap *bm; BYTE * bmbits = NULL; GetObject(hbmp,sizeof(BITMAP),&bmp); Graphics g(hDestDC); if (bmp.bmBitsPixel == 32 && (flag&AVS_PREMULTIPLIED)) { bmbits = (BYTE*)bmp.bmBits; if ( !bmbits) { bmbits = (BYTE*)malloc(bmp.bmHeight*bmp.bmWidthBytes); GetBitmapBits(hbmp,bmp.bmHeight*bmp.bmWidthBytes,bmbits); } bm = new Bitmap(bmp.bmWidth,bmp.bmHeight,bmp.bmWidthBytes,PixelFormat32bppPARGB,bmbits); bm->RotateFlip(RotateNoneFlipY); if ( !bmp.bmBits) { bm->RotateFlip(RotateNoneFlipY); free(bmbits); } } else bm = new Bitmap(hbmp,NULL); ImageAttributes attr; ColorMatrix ClrMatrix = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, ((float)alpha)/255, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; attr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap); g.SetInterpolationMode(InterpolationModeHighQualityBicubic); RectF rect((float)x,(float)y,(float)width,(float)height); g.DrawImage(bm, rect, (float)x1, (float)y1, (float)width1, (float)height1 , UnitPixel, &attr, NULL, NULL); delete bm; } BOOL GDIPlus_AlphaBlend(HDC hdcDest,int nXOriginDest,int nYOriginDest,int nWidthDest,int nHeightDest,HDC hdcSrc,int nXOriginSrc,int nYOriginSrc,int nWidthSrc,int nHeightSrc, BLENDFUNCTION * bf) { Graphics g(hdcDest); BITMAP bmp; HBITMAP hbmp = (HBITMAP)GetCurrentObject(hdcSrc,OBJ_BITMAP); GetObject(hbmp,sizeof(BITMAP),&bmp); Bitmap *bm = new Bitmap(hbmp,NULL); if (bmp.bmBitsPixel == 32 && bf->AlphaFormat) { bm = new Bitmap(bmp.bmWidth,bmp.bmHeight,bmp.bmWidthBytes,PixelFormat32bppPARGB,(BYTE*)bmp.bmBits); bm->RotateFlip(RotateNoneFlipY); } else bm = new Bitmap(hbmp,NULL); ImageAttributes attr; ColorMatrix ClrMatrix = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, ((float)bf->SourceConstantAlpha)/255, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; attr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap); if (bf->BlendFlags&128 && nWidthDest < nWidthSrc && nHeightDest < nHeightSrc) { g.SetInterpolationMode(InterpolationModeHighQualityBicubic); g.SetPixelOffsetMode(PixelOffsetModeHalf); attr.SetGamma((REAL)0.8,ColorAdjustTypeBitmap); } else { g.SetInterpolationMode(InterpolationModeLowQuality); //g.SetPixelOffsetMode(PixelOffsetModeHalf); } RectF rect((float)nXOriginDest,(float)nYOriginDest,(float)nWidthDest,(float)nHeightDest); g.DrawImage(bm, rect, (float)nXOriginSrc, (float)nYOriginSrc, (float)nWidthSrc, (float)nHeightSrc , UnitPixel, &attr, NULL, NULL); delete bm; return TRUE; } COLORREF __inline _revcolref(COLORREF colref) { return RGB(GetBValue(colref), GetGValue(colref), GetRValue(colref)); } ///////////////////////////////////////////////////////////////////////////////// // GDIPlus_IsAnimatedGIF and GDIPlus_ExtractAnimatedGIF // based on routine from http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp // BOOL GDIPlus_IsAnimatedGif (TCHAR * szName) { int nFrameCount = 0; Image image(szName); UINT count = 0; count = image.GetFrameDimensionsCount(); GUID* pDimensionIDs = new GUID[count]; // Get the list of frame dimensions from the Image object. image.GetFrameDimensionsList(pDimensionIDs, count); // Get the number of frames in the first dimension. nFrameCount = image.GetFrameCount(&pDimensionIDs[0]); delete[] pDimensionIDs; return (BOOL) (nFrameCount > 1); } void GDIPlus_ExtractAnimatedGIF (TCHAR * szName, int width, int height, HBITMAP * pBitmap, int ** pframesDelay, int * pframesCount, SIZE * pSizeAvatar) { int nFrameCount = 0; Bitmap image(szName); PropertyItem * pPropertyItem; UINT count = 0; count = image.GetFrameDimensionsCount(); GUID* pDimensionIDs = new GUID[count]; // Get the list of frame dimensions from the Image object. image.GetFrameDimensionsList(pDimensionIDs, count); // Get the number of frames in the first dimension. nFrameCount = image.GetFrameCount(&pDimensionIDs[0]); // Assume that the image has a property item of type PropertyItemEquipMake. // Get the size of that property item. int nSize = image.GetPropertyItemSize(PropertyTagFrameDelay); // Allocate a buffer to receive the property item. pPropertyItem = (PropertyItem*) malloc(nSize); image.GetPropertyItem(PropertyTagFrameDelay, nSize, pPropertyItem); int clipWidth; int clipHeight; int imWidth = image.GetWidth(); int imHeight = image.GetHeight(); float xscale = (float)width/imWidth; float yscale = (float)height/imHeight; xscale = min(xscale,yscale); clipWidth = (int)(xscale*imWidth+.5); clipHeight = (int)(xscale*imHeight+.5); HBITMAP hBitmap = ske_CreateDIB32(clipWidth*nFrameCount, height); HDC hdc = CreateCompatibleDC(NULL); HBITMAP oldBmp = (HBITMAP)SelectObject(hdc,hBitmap); Graphics graphics(hdc); ImageAttributes attr; graphics.SetInterpolationMode( InterpolationModeHighQualityBicubic ); graphics.SetPixelOffsetMode( PixelOffsetModeHalf ); int * delays = (int*)malloc(nFrameCount*sizeof(int)); memset(delays,0,nFrameCount*sizeof(int)); GUID pageGuid = FrameDimensionTime; /* The GDIPlus strange behavior: without next 2 lines it will draw first frame anti aliased, but next - not */ if ( nFrameCount > 1 ) image.SelectActiveFrame(&pageGuid, 1 ); for (int i=0; i < nFrameCount; i++) { image.SelectActiveFrame( &pageGuid, i ); graphics.DrawImage( &image, Rect(i*clipWidth, 0,clipWidth,clipHeight ), 0, 0, imWidth, imHeight , UnitPixel, &attr); long lPause = ((long*) pPropertyItem->value)[i] * 10; delays[i] = (int)lPause; } SelectObject(hdc,oldBmp); DeleteDC(hdc); free(pPropertyItem); delete[] pDimensionIDs; if (pBitmap && pframesDelay && pframesCount && pSizeAvatar) { *pBitmap = hBitmap; *pframesDelay = delays; *pframesCount = nFrameCount; pSizeAvatar->cx = clipWidth; pSizeAvatar->cy = clipHeight; } GdiFlush(); }