summaryrefslogtreecommitdiff
path: root/plugins/Popup/src/popup_gdiplus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Popup/src/popup_gdiplus.cpp')
-rw-r--r--plugins/Popup/src/popup_gdiplus.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/plugins/Popup/src/popup_gdiplus.cpp b/plugins/Popup/src/popup_gdiplus.cpp
new file mode 100644
index 0000000000..186fedb238
--- /dev/null
+++ b/plugins/Popup/src/popup_gdiplus.cpp
@@ -0,0 +1,223 @@
+/*
+Popup Plus plugin for Miranda IM
+
+Copyright � 2002 Luca Santarelli,
+ � 2004-2007 Victor Pavlychko
+ � 2010 MPK
+ � 2010 Merlin_de
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+===============================================================================
+
+File name : $HeadURL: http://svn.miranda.im/mainrepo/popup/trunk/src/popup_gdiplus.cpp $
+Revision : $Revision: 1622 $
+Last change on : $Date: 2010-06-23 23:32:21 +0300 (Ср, 23 июн 2010) $
+Last change by : $Author: Merlin_de $
+
+===============================================================================
+*/
+
+/* 99% of this code was adopted from clist_modern by FYR */
+
+#include "headers.h"
+
+#undef Translate
+
+// fix for old SDK and new GDI+
+#define ULONG_PTR unsigned long
+
+#include "gdiplus.h"
+
+DWORD g_gdiplusToken;
+bool gbGdiPlusLoaded;
+
+void LoadGDIPlus()
+{
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ gbGdiPlusLoaded = false;
+ __try {
+ if (g_gdiplusToken == 0)
+ Gdiplus::GdiplusStartup(&g_gdiplusToken, &gdiplusStartupInput, NULL);
+ }
+ __except ( EXCEPTION_EXECUTE_HANDLER ) {
+ gbGdiPlusLoaded = false;
+ }
+}
+
+void UnloadGDIPlus()
+{
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ __try {
+ if (g_gdiplusToken && gbGdiPlusLoaded)
+ Gdiplus::GdiplusShutdown(g_gdiplusToken);
+ }
+ __except ( EXCEPTION_EXECUTE_HANDLER ) {
+ // do nothing
+ }
+ gbGdiPlusLoaded = true;
+ g_gdiplusToken = 0;
+}
+
+using namespace Gdiplus;
+
+/////////////////////////////////////////////////////////////////////////////////
+// GDIPlus_IsAnimatedGIF and GDIPlus_ExtractAnimatedGIF
+// based on routine from http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp
+//
+
+HBITMAP SkinEngine_CreateDIB32(int cx, int cy)
+{
+ BITMAPINFO RGB32BitsBITMAPINFO;
+ UINT * ptPixels;
+ HBITMAP DirectBitmap;
+
+ if ( cx < 0 || cy < 0 ) {
+ return NULL;
+ }
+
+ ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
+ RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth;
+ RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight;
+ RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
+ RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
+ // pointer used for direct Bitmap pixels access
+
+
+ DirectBitmap = CreateDIBSection(NULL,
+ (BITMAPINFO *)&RGB32BitsBITMAPINFO,
+ DIB_RGB_COLORS,
+ (void **)&ptPixels,
+ NULL, 0);
+ if ((DirectBitmap == NULL || ptPixels == NULL) && cx!= 0 && cy!=0)
+ {
+ ;
+ }
+ else
+ {
+ memset(ptPixels,0,cx*cy*4);
+ }
+ return DirectBitmap;
+}
+
+
+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) && image.GetWidth() && image.GetHeight();
+}
+
+void GDIPlus_GetGIFSize(TCHAR * szName, int * width, int * height)
+{
+ Image image(szName);
+
+ *width = image.GetWidth();
+ *height = image.GetHeight();
+}
+
+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*) mir_alloc(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=SkinEngine_CreateDIB32(clipWidth*nFrameCount, height);
+ HDC hdc=CreateCompatibleDC(NULL);
+ HBITMAP oldBmp=(HBITMAP)SelectObject(hdc,hBitmap);
+ Graphics graphics(hdc);
+ 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)255)/255, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
+ };
+ //attr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);
+ graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
+
+ int * delays=(int*)mir_alloc(nFrameCount*sizeof(int));
+ memset(delays,0,nFrameCount*sizeof(int));
+
+ for (int i=1; i<nFrameCount+1; i++)
+ {
+ GUID pageGuid = FrameDimensionTime;
+ RectF rect((float)(i-1)*clipWidth,(float)0,(float)clipWidth,(float)clipHeight);
+ graphics.DrawImage(&image, rect, (float)0, (float)0, (float)imWidth, (float)imHeight , UnitPixel, &attr, NULL, NULL);
+ image.SelectActiveFrame(&pageGuid, i);
+ long lPause = ((long*) pPropertyItem->value)[i-1] * 10;
+ delays[i-1]=(int)lPause;
+ }
+ SelectObject(hdc,oldBmp);
+ DeleteDC(hdc);
+ mir_free(pPropertyItem);
+ pPropertyItem = NULL;
+ delete []pDimensionIDs;
+ if (pBitmap && pframesDelay && pframesCount && pSizeAvatar)
+ {
+ *pBitmap=hBitmap;
+ *pframesDelay=delays;
+ *pframesCount=nFrameCount;
+ pSizeAvatar->cx=clipWidth;
+ pSizeAvatar->cy=clipHeight;
+ }
+ GdiFlush();
+}