vcpkg/ports/duilib/fix-encoding.patch

375 lines
10 KiB
Diff
Raw Normal View History

diff --git a/DuiLib/Control/UIGifAnim-patch.cpp b/DuiLib/Control/UIGifAnim-patch.cpp
new file mode 100644
index 0000000..61aa32f
--- /dev/null
+++ b/DuiLib/Control/UIGifAnim-patch.cpp
@@ -0,0 +1,368 @@
+#include "StdAfx.h"
+#include "UIGifAnim.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that has been opened
+typedef DWORD ZRESULT;
+typedef struct
+{
+ int index; // index of this file within the zip
+ char name[MAX_PATH]; // filename within the zip
+ DWORD attr; // attributes, as in GetFileAttributes.
+ FILETIME atime,ctime,mtime;// access, create, modify filetimes
+ long comp_size; // sizes of item, compressed and uncompressed. These
+ long unc_size; // may be -1 if not yet known (e.g. being streamed in)
+} ZIPENTRY;
+typedef struct
+{
+ int index; // index of this file within the zip
+ TCHAR name[MAX_PATH]; // filename within the zip
+ DWORD attr; // attributes, as in GetFileAttributes.
+ FILETIME atime,ctime,mtime;// access, create, modify filetimes
+ long comp_size; // sizes of item, compressed and uncompressed. These
+ long unc_size; // may be -1 if not yet known (e.g. being streamed in)
+} ZIPENTRYW;
+#define OpenZip OpenZipU
+#define CloseZip(hz) CloseZipU(hz)
+extern HZIP OpenZipU(void *z,unsigned int len,DWORD flags);
+extern ZRESULT CloseZipU(HZIP hz);
+#ifdef _UNICODE
+#define ZIPENTRY ZIPENTRYW
+#define GetZipItem GetZipItemW
+#define FindZipItem FindZipItemW
+#else
+#define GetZipItem GetZipItemA
+#define FindZipItem FindZipItemA
+#endif
+extern ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze);
+extern ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *ze);
+extern ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
+extern ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *ze);
+extern ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags);
+///////////////////////////////////////////////////////////////////////////////////////
+
+namespace DuiLib
+{
+
+ CGifAnimUI::CGifAnimUI(void)
+ {
+ m_pGifImage = NULL;
+ m_pPropertyItem = NULL;
+ m_nFrameCount = 0;
+ m_nFramePosition = 0;
+ m_bIsAutoPlay = true;
+ m_bIsAutoSize = false;
+ m_bIsPlaying = false;
+ m_pStream = NULL;
+ }
+
+
+ CGifAnimUI::~CGifAnimUI(void)
+ {
+ DeleteGif();
+ m_pManager->KillTimer( this, EVENT_TIEM_ID );
+
+ }
+
+ LPCTSTR CGifAnimUI::GetClass() const
+ {
+ return DUI_CTR_GIFANIM;
+ }
+
+ LPVOID CGifAnimUI::GetInterface( LPCTSTR pstrName )
+ {
+ if( _tcscmp(pstrName, DUI_CTR_GIFANIM) == 0 ) return static_cast<CGifAnimUI*>(this);
+ return CControlUI::GetInterface(pstrName);
+ }
+
+ void CGifAnimUI::DoInit()
+ {
+ InitGifImage();
+ }
+
+ bool CGifAnimUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
+ {
+ if ( NULL == m_pGifImage )
+ {
+ InitGifImage();
+ }
+ DrawFrame( hDC );
+ return true;
+ }
+
+ void CGifAnimUI::DoEvent( TEventUI& event )
+ {
+ if( event.Type == UIEVENT_TIMER )
+ OnTimer( (UINT_PTR)event.wParam );
+ }
+
+ void CGifAnimUI::SetVisible(bool bVisible /* = true */)
+ {
+ CControlUI::SetVisible(bVisible);
+ if (bVisible)
+ PlayGif();
+ else
+ StopGif();
+ }
+
+ void CGifAnimUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
+ {
+ if( _tcscmp(pstrName, _T("bkimage")) == 0 ) SetBkImage(pstrValue);
+ else if( _tcscmp(pstrName, _T("autoplay")) == 0 ) {
+ SetAutoPlay(_tcscmp(pstrValue, _T("true")) == 0);
+ }
+ else if( _tcscmp(pstrName, _T("autosize")) == 0 ) {
+ SetAutoSize(_tcscmp(pstrValue, _T("true")) == 0);
+ }
+ else
+ CControlUI::SetAttribute(pstrName, pstrValue);
+ }
+
+ void CGifAnimUI::SetBkImage(LPCTSTR pStrImage)
+ {
+ if( m_sBkImage == pStrImage || NULL == pStrImage) return;
+
+ m_sBkImage = pStrImage;
+
+ StopGif();
+ DeleteGif();
+
+ Invalidate();
+
+ }
+
+ LPCTSTR CGifAnimUI::GetBkImage()
+ {
+ return m_sBkImage.GetData();
+ }
+
+ void CGifAnimUI::SetAutoPlay(bool bIsAuto)
+ {
+ m_bIsAutoPlay = bIsAuto;
+ }
+
+ bool CGifAnimUI::IsAutoPlay() const
+ {
+ return m_bIsAutoPlay;
+ }
+
+ void CGifAnimUI::SetAutoSize(bool bIsAuto)
+ {
+ m_bIsAutoSize = bIsAuto;
+ }
+
+ bool CGifAnimUI::IsAutoSize() const
+ {
+ return m_bIsAutoSize;
+ }
+
+ void CGifAnimUI::PlayGif()
+ {
+ if (m_bIsPlaying || m_pGifImage == NULL)
+ {
+ return;
+ }
+
+ long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
+ if ( lPause == 0 ) lPause = 100;
+ m_pManager->SetTimer( this, EVENT_TIEM_ID, lPause );
+
+ m_bIsPlaying = true;
+ }
+
+ void CGifAnimUI::PauseGif()
+ {
+ if (!m_bIsPlaying || m_pGifImage == NULL)
+ {
+ return;
+ }
+
+ m_pManager->KillTimer(this, EVENT_TIEM_ID);
+ this->Invalidate();
+ m_bIsPlaying = false;
+ }
+
+ void CGifAnimUI::StopGif()
+ {
+ if (!m_bIsPlaying)
+ {
+ return;
+ }
+
+ m_pManager->KillTimer(this, EVENT_TIEM_ID);
+ m_nFramePosition = 0;
+ this->Invalidate();
+ m_bIsPlaying = false;
+ }
+
+ void CGifAnimUI::InitGifImage()
+ {
+ m_pGifImage = LoadGifFromFile(GetBkImage());
+ if ( NULL == m_pGifImage ) return;
+ UINT nCount = 0;
+ nCount = m_pGifImage->GetFrameDimensionsCount();
+ GUID* pDimensionIDs = new GUID[ nCount ];
+ m_pGifImage->GetFrameDimensionsList( pDimensionIDs, nCount );
+ m_nFrameCount = m_pGifImage->GetFrameCount( &pDimensionIDs[0] );
+ int nSize = m_pGifImage->GetPropertyItemSize( PropertyTagFrameDelay );
+ m_pPropertyItem = (Gdiplus::PropertyItem*) malloc( nSize );
+ m_pGifImage->GetPropertyItem( PropertyTagFrameDelay, nSize, m_pPropertyItem );
+ delete[] pDimensionIDs;
+ pDimensionIDs = NULL;
+
+ if (m_bIsAutoSize)
+ {
+ SetFixedWidth(m_pGifImage->GetWidth());
+ SetFixedHeight(m_pGifImage->GetHeight());
+ }
+ if (m_bIsAutoPlay && nSize > 0)
+ {
+ PlayGif();
+ }
+ }
+
+ void CGifAnimUI::DeleteGif()
+ {
+ if (m_pStream != NULL )
+ {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+ if ( m_pGifImage != NULL )
+ {
+ delete m_pGifImage;
+ m_pGifImage = NULL;
+ }
+
+ if ( m_pPropertyItem != NULL )
+ {
+ free( m_pPropertyItem );
+ m_pPropertyItem = NULL;
+ }
+ m_nFrameCount = 0;
+ m_nFramePosition = 0;
+ }
+
+ void CGifAnimUI::OnTimer( UINT_PTR idEvent )
+ {
+ if ( idEvent != EVENT_TIEM_ID )
+ return;
+ m_pManager->KillTimer( this, EVENT_TIEM_ID );
+ this->Invalidate();
+
+ m_nFramePosition = (++m_nFramePosition) % m_nFrameCount;
+
+ long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
+ if ( lPause == 0 ) lPause = 100;
+ m_pManager->SetTimer( this, EVENT_TIEM_ID, lPause );
+ }
+
+ void CGifAnimUI::DrawFrame( HDC hDC )
+ {
+ if ( NULL == hDC || NULL == m_pGifImage ) return;
+ GUID pageGuid = Gdiplus::FrameDimensionTime;
+ Gdiplus::Graphics graphics( hDC );
+ graphics.DrawImage( m_pGifImage, m_rcItem.left, m_rcItem.top, m_rcItem.right-m_rcItem.left, m_rcItem.bottom-m_rcItem.top );
+ m_pGifImage->SelectActiveFrame( &pageGuid, m_nFramePosition );
+ }
+
+ Gdiplus::Image* CGifAnimUI::LoadGifFromFile(LPCTSTR pstrGifPath)
+ {
+ LPBYTE pData = NULL;
+ DWORD dwSize = 0;
+
+ do
+ {
+ CDuiString sFile = CPaintManagerUI::GetResourcePath();
+ if( CPaintManagerUI::GetResourceZip().IsEmpty() ) {
+ sFile += pstrGifPath;
+ HANDLE hFile = ::CreateFile(sFile.GetData(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if( hFile == INVALID_HANDLE_VALUE ) break;
+ dwSize = ::GetFileSize(hFile, NULL);
+ if( dwSize == 0 ) break;
+
+ DWORD dwRead = 0;
+ pData = new BYTE[ dwSize ];
+ ::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
+ ::CloseHandle( hFile );
+
+ if( dwRead != dwSize ) {
+ delete[] pData;
+ pData = NULL;
+ break;
+ }
+ }
+ else {
+ sFile += CPaintManagerUI::GetResourceZip();
+ HZIP hz = NULL;
+ if( CPaintManagerUI::IsCachedResourceZip() ) hz = (HZIP)CPaintManagerUI::GetResourceZipHandle();
+ else hz = OpenZip((void*)sFile.GetData(), 0, 2);
+ if( hz == NULL ) break;
+ ZIPENTRY ze;
+ int i;
+ if( FindZipItem(hz, pstrGifPath, true, &i, &ze) != 0 ) break;
+ dwSize = ze.unc_size;
+ if( dwSize == 0 ) break;
+ pData = new BYTE[ dwSize ];
+ int res = UnzipItem(hz, i, pData, dwSize, 3);
+ if( res != 0x00000000 && res != 0x00000600) {
+ delete[] pData;
+ pData = NULL;
+ if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
+ break;
+ }
+ if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
+ }
+
+ } while (0);
+
+ while (!pData)
+ {
+ HANDLE hFile = ::CreateFile(pstrGifPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if( hFile == INVALID_HANDLE_VALUE ) break;
+ dwSize = ::GetFileSize(hFile, NULL);
+ if( dwSize == 0 ) break;
+
+ DWORD dwRead = 0;
+ pData = new BYTE[ dwSize ];
+ ::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
+ ::CloseHandle( hFile );
+
+ if( dwRead != dwSize ) {
+ delete[] pData;
+ pData = NULL;
+ }
+ break;
+ }
+ if (!pData)
+ {
+ return NULL;
+ }
+
+ Gdiplus::Image* pImage = LoadGifFromMemory(pData, dwSize);
+ delete[] pData;
+ return pImage;
+ }
+
+ Gdiplus::Image* CGifAnimUI::LoadGifFromMemory( LPVOID pBuf,size_t dwSize )
+ {
+ HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
+ BYTE* pMem = (BYTE*)::GlobalLock(hMem);
+
+ memcpy(pMem, pBuf, dwSize);
+ ::GlobalUnlock(hMem);
+
+ ::CreateStreamOnHGlobal(hMem, TRUE, &m_pStream);
+ Gdiplus::Image *pImg = Gdiplus::Image::FromStream(m_pStream);
+ if(!pImg || pImg->GetLastStatus() != Gdiplus::Ok)
+ {
+ m_pStream->Release();
+ m_pStream = NULL;
+ return 0;
+ }
+ return pImg;
+ }
+
+}