From 6b3ded37e4a4825be2df3612bdcbb7dfc00a1800 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 4 Mar 2014 20:41:13 +0000 Subject: HistoryStats sources git-svn-id: http://svn.miranda-ng.org/main/trunk@8397 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!NotAdopted/HistoryStats/canvas.cpp | 228 ++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 plugins/!NotAdopted/HistoryStats/canvas.cpp (limited to 'plugins/!NotAdopted/HistoryStats/canvas.cpp') diff --git a/plugins/!NotAdopted/HistoryStats/canvas.cpp b/plugins/!NotAdopted/HistoryStats/canvas.cpp new file mode 100644 index 0000000000..2444432ad1 --- /dev/null +++ b/plugins/!NotAdopted/HistoryStats/canvas.cpp @@ -0,0 +1,228 @@ +#include "_globals.h" +#include "canvas.h" + +void Canvas::updateTrans(BYTE* pData) +{ + // MEMO: this follwing transparency code only makes sense for m_nChannels == 4 + assert(m_nChannels == 4); + + // apply transparency, if any + if (m_bTransColor) + { + for (int y = 0; y < m_nHeight; ++y) + { + COLORREF* pValue = reinterpret_cast(pData + y * m_nLineLength); + + for (int x = 0; x < m_nWidth; ++x) + { + *pValue = (*pValue & 0x00FFFFFF) | ((*pValue & 0x00FFFFFF) == m_TransColor ? 0x00000000 : 0xFF000000); + ++pValue; + } + } + } + else + { + for (int y = 0; y < m_nHeight; ++y) + { + COLORREF* pValue = reinterpret_cast(pData + y * m_nLineLength); + + for (int x = 0; x < m_nWidth; ++x) + { + *pValue |= 0xFF000000; + ++pValue; + } + } + } +} + +Canvas::Canvas(int nWidth, int nHeight) + : m_nChannels(4) + , m_nWidth(nWidth) + , m_nHeight(nHeight) + , m_nLineLength((m_nChannels * m_nWidth + 3) & ~0x3) + , m_bTransColor(false) + , m_TransColor(0) + , m_pBMIH(NULL) +{ +} + +Canvas::~Canvas() +{ + if (m_hOldBmp) + { + SelectObject(m_hDC, m_hOldBmp); + } + + if (m_hBmp) + { + DeleteObject(m_hBmp); + } + + if (m_hDC) + { + DeleteDC(m_hDC); + } + + delete m_pBMIH; +} + +void Canvas::setTrans(COLORREF transColor, bool bFill /* = false */) +{ + m_bTransColor = true; + m_TransColor = transColor; + + if (bFill) + { + fillBackground(transColor); + } +} + +void Canvas::fillBackground(COLORREF bkColor) +{ + HDC hDC = beginDraw(); + + RECT rAll = { 0, 0, m_nWidth, m_nHeight }; + + SetBkColor(hDC, bkColor); + ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rAll, NULL, 0, NULL); + + endDraw(); +} + +HDC Canvas::beginDraw() +{ + if (!m_pBMIH) + { + m_pBMIH = new BITMAPINFOHEADER; + + m_pBMIH->biSize = sizeof(BITMAPINFOHEADER); + m_pBMIH->biWidth = m_nWidth; + m_pBMIH->biHeight = m_nHeight; + m_pBMIH->biPlanes = 1; + m_pBMIH->biBitCount = 8 * m_nChannels; + m_pBMIH->biCompression = BI_RGB; + m_pBMIH->biSizeImage = m_nChannels * m_nWidth * m_nHeight; + m_pBMIH->biXPelsPerMeter = 0; + m_pBMIH->biYPelsPerMeter = 0; + m_pBMIH->biClrUsed = 0; + m_pBMIH->biClrImportant = 0; + + BYTE* pData = 0; + + m_hDC = CreateCompatibleDC(NULL); + m_hBmp = CreateDIBSection(m_hDC, reinterpret_cast(m_pBMIH), DIB_RGB_COLORS, reinterpret_cast(&pData), NULL, 0); + } + + m_hOldBmp = SelectObject(m_hDC, m_hBmp); + + return m_hDC; +} + +void Canvas::endDraw() +{ + SelectObject(m_hDC, m_hOldBmp); + m_hOldBmp = NULL; +} + +bool Canvas::getDigest(Digest& digest) +{ + // we don't have a digest if the image is uninitialized + if (!m_pBMIH) + { + return false; + } + + if (mu::sha1::_available()) + { + // read data from DIB + int nSize = m_nLineLength * m_nHeight; + BYTE* pData = new BYTE[nSize]; + + ZeroMemory(pData, nSize); + + if (GetDIBits(m_hDC, m_hBmp, 0, m_nHeight, pData, reinterpret_cast(m_pBMIH), DIB_RGB_COLORS) != m_nHeight) + { + delete[] pData; + + return false; + } + + // apply transparency, if any + updateTrans(pData); + + // calculate hash + SHA1_INTERFACE sha1i = mu::sha1::getInterface(); + + sha1i.sha1_hash(pData, nSize, digest.m_Digest); + + delete[] pData; + } + else + { + // fallback digest if no SHA1 interface is available + static int nUniqueID = 0; + + *reinterpret_cast(digest.m_Digest) = ++nUniqueID; + } + + return true; +} + +bool Canvas::writePNG(const mu_text* szFileName) +{ + // read data from DIB + BYTE* pData = new BYTE[m_nLineLength * m_nHeight]; + + if (GetDIBits(m_hDC, m_hBmp, 0, m_nHeight, pData, reinterpret_cast(m_pBMIH), DIB_RGB_COLORS) != m_nHeight) + { + delete[] pData; + + return false; + } + + // apply transparency, if any + updateTrans(pData); + + // calculate resulting image size + long png_len = 0; + + if (!mu::png::dibToPng(m_pBMIH, pData, 0, &png_len) || png_len == 0) + { + delete[] pData; + + return false; + } + + // get the resulting image data + BYTE* pRawPNG = new BYTE[png_len]; + + png_len = 0; + + if (!mu::png::dibToPng(m_pBMIH, pData, pRawPNG, &png_len)) + { + delete[] pData; + delete[] pRawPNG; + + return false; + } + + // write image data to file + FILE* fp = _tfopen(szFileName, muT("wb")); + + if (!fp) + { + delete[] pData; + delete[] pRawPNG; + + return false; + } + + fwrite(pRawPNG, 1, png_len, fp); + fclose(fp); + + // free buffers + delete[] pRawPNG; + delete[] pData; + + return true; +} -- cgit v1.2.3