Files
core/ASCImageStudio3/ASCGraphics/agg/ASCWrapper/DIB.h

543 lines
14 KiB
C++
Raw Blame History

#pragma once
#include "math.h"
//#include "GdiplusEx.h"
#include "..\Interfaces\ASCRenderer.h"
namespace NSDocumentViewer
{
const double c_dInch_to_MM = 25.4;
enum ViewMode
{
FitPage = 0,
FitWidth = 1,
FitHeight = 2,
Custom = 3
};
class CDoublePoint
{
public:
double x;
double y;
public:
CDoublePoint()
{
x = 0;
y = 0;
}
CDoublePoint(double dx, double dy)
{
x = dx;
y = dy;
}
CDoublePoint& operator=(const CDoublePoint& oSrc)
{
x = oSrc.x;
y = oSrc.y;
return *this;
}
CDoublePoint(const CDoublePoint& oSrc)
{
*this = oSrc;
}
};
class CDoubleRect
{
public:
double left;
double top;
double right;
double bottom;
public:
CDoubleRect()
{
left = 0;
top = 0;
right = 0;
bottom = 0;
}
CDoubleRect& operator=(const CDoubleRect& oSrc)
{
left = oSrc.left;
top = oSrc.top;
right = oSrc.right;
bottom = oSrc.bottom;
return *this;
}
CDoubleRect(const CDoubleRect& oSrc)
{
*this = oSrc;
}
inline double GetWidth() const
{
return right - left;
}
inline double GetHeight() const
{
return bottom - top;
}
inline void Offset(double dX, double dY)
{
left += dX;
top += dY;
right += dX;
bottom += dY;
}
inline double GetCentreX() const
{
return (left + right) / 2.0;
}
inline double GetCentreY() const
{
return (top + bottom) / 2.0;
}
inline BOOL IsPointInside(const CDoublePoint& oPoint)
{
return IsPointInside(oPoint.x, oPoint.y);
}
BOOL IsPointInside(const double& pointX, const double& pointY)
{
return ((left <= pointX) && (right >= pointX) &&
(top <= pointY) && (bottom >= pointY));
}
};
class CPainter
{
public:
BITMAPINFO m_infoDC;
LONG m_lDisplayWidth;
LONG m_lDisplayHeight;
BYTE* m_pPixels;
HDC m_hDC;
HDC m_hMemDC;
IASCRenderer* m_pRenderer;
double m_dKoefPixToMM_X;
double m_dKoefPixToMM_Y;
public:
CPainter()
{
memset(&m_infoDC, 0, sizeof(BITMAPINFO));
m_infoDC.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//m_infoDC.bmiHeader.biWidth = 0;
//m_infoDC.bmiHeader.biHeight = 0;
m_infoDC.bmiHeader.biPlanes = 1;
m_infoDC.bmiHeader.biBitCount = 32;
m_infoDC.bmiHeader.biCompression = BI_RGB;
//m_infoDC.bmiHeader.biSizeImage = 0 * 0 * 4;
m_pRenderer = NULL;
}
~CPainter()
{
RELEASEINTERFACE(m_pRenderer);
}
public:
void SetDisplayInfo(BYTE* pPixels, LONG lWidth, LONG lHeight)
{
m_pPixels = pPixels;
m_lDisplayWidth = lWidth;
m_lDisplayHeight = lHeight;
}
void SetDpi(double dDpiX, double dDpiY);
void SetDC(HDC hDC, HDC hMemDC)
{
m_hDC = hDC;
m_hMemDC = hMemDC;
}
public:
inline void SetSize(const LONG& lWidth, const LONG& lHeight)
{
m_infoDC.bmiHeader.biWidth = lWidth;
m_infoDC.bmiHeader.biHeight = lHeight;
m_infoDC.bmiHeader.biSizeImage = lWidth * lHeight * 4;
}
inline void Render(HDC hDC, RECT rect, BYTE* pBuffer)
{
LONG lWidth = rect.right - rect.left;
LONG lHeight = rect.bottom - rect.top;
SetSize(lWidth, lHeight);
SetDIBitsToDevice(hDC, rect.left, rect.top, lWidth, lHeight, 0, 0, 0, lHeight,
(void*)pBuffer, &m_infoDC, DIB_RGB_COLORS);
}
inline void RenderStretch(HDC hDC, RECT rect, BYTE* pBufferBGRA, LONG lSrcWidth, LONG lSrcHeight, LONG lSrcX = 0, LONG lSrcY = 0)
{
//LONG lWidth = rect.right - rect.left;
//LONG lHeight = rect.bottom - rect.top;
SetSize(lSrcWidth, lSrcHeight);
StretchDIBits(hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
lSrcX, lSrcY, lSrcWidth, lSrcHeight, pBufferBGRA, &m_infoDC, DIB_RGB_COLORS, SRCCOPY);
}
public:
void BlitPixels()
{
SetSize(m_lDisplayWidth, m_lDisplayHeight);
SetDIBitsToDevice(m_hDC, 0, 0, m_lDisplayWidth, m_lDisplayHeight, 0, 0, 0, m_lDisplayHeight,
(void*)m_pPixels, &m_infoDC, DIB_RGB_COLORS);
}
void BlitPage(BYTE* pPixelsPage, RECT rect, LONG lSrcWidth, LONG lSrcHeight)
{
LONG lDrawWidth = rect.right - rect.left;
LONG lDrawHeight = rect.bottom - rect.top;
if ((lDrawWidth == lSrcWidth) && (lDrawHeight == lSrcHeight))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LONG leftBuffer = 0;
LONG leftDisplay = rect.left;
if (rect.left < 0)
{
leftBuffer = -leftDisplay;
leftDisplay = 0;
}
LONG topBuffer = 0;
LONG topDisplay = rect.top;
if (rect.top < 0)
{
topBuffer = -topDisplay;
topDisplay = 0;
}
LONG bottomDisplay = min(rect.bottom, m_lDisplayHeight - 1);
LONG lCopy = 4 * min(m_lDisplayWidth - leftDisplay, lSrcWidth);
//BYTE* pDisplayMem = m_pPixels + 4 * (leftDisplay + topDisplay * m_lDisplayWidth);
BYTE* pDisplayMem = m_pPixels + 4 * (m_lDisplayHeight - 1) * m_lDisplayWidth;
pDisplayMem += 4 * (leftDisplay - topDisplay * m_lDisplayWidth);
//BYTE* pBufferMem = pPixelsPage + 4 * (leftBuffer + topBuffer * lSrcWidth);
BYTE* pBufferMem = pPixelsPage + 4 * (lSrcHeight - 1) * lSrcWidth;
pBufferMem += 4 * (leftBuffer - topBuffer * lSrcWidth);
for (LONG i = topDisplay; i < bottomDisplay; ++i)
{
memcpy(pDisplayMem, pBufferMem, lCopy);
pDisplayMem -= 4 * m_lDisplayWidth;
pBufferMem -= 4 * lSrcWidth;
}
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>+
Gdiplus::Bitmap oDisplayImage(m_lDisplayWidth, m_lDisplayHeight, 4 * m_lDisplayWidth, PixelFormat32bppARGB, m_pPixels);
Gdiplus::Bitmap oBufferImage(lSrcWidth, lSrcHeight, 4 * lSrcWidth, PixelFormat32bppARGB, pPixelsPage);
Gdiplus::Graphics oRender(&oDisplayImage);
oRender.DrawImage(&oBufferImage, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
}
void BlitPage2(BYTE* pPixelsPage, RECT rect, LONG lSrcWidth, LONG lSrcHeight)
{
SetSize(lSrcWidth, lSrcHeight);
SetStretchBltMode(m_hDC, COLORONCOLOR);
StretchDIBits(m_hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
0, 0, lSrcWidth, lSrcHeight, pPixelsPage, &m_infoDC, DIB_RGB_COLORS, SRCCOPY);
}
void BlitPage3(BYTE* pPixelsPage, RECT rect, LONG lSrcWidth, LONG lSrcHeight)
{
SetSize(lSrcWidth, lSrcHeight);
SetStretchBltMode(m_hMemDC, COLORONCOLOR);
StretchDIBits(m_hMemDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
0, 0, lSrcWidth, lSrcHeight, pPixelsPage, &m_infoDC, DIB_RGB_COLORS, SRCCOPY);
}
};
class CDIB
{
public:
BYTE* m_pBits;
LONG m_lWidth;
LONG m_lHeight;
HBITMAP m_hBitmap;
public:
HANDLE m_hFile;
HANDLE m_hSection;
BITMAPINFO* m_pInfo;
public:
CDIB() : m_hBitmap(NULL), m_hFile(NULL), m_hSection(NULL)
{
UINT nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 0;
m_pInfo = (LPBITMAPINFO)malloc(nSize);
ZeroMemory(&m_pInfo->bmiHeader, sizeof(m_pInfo->bmiHeader));
m_pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pInfo->bmiHeader.biWidth = 0;
m_pInfo->bmiHeader.biHeight = 0;
m_pInfo->bmiHeader.biBitCount = 32;
m_pInfo->bmiHeader.biCompression = BI_RGB;
m_pInfo->bmiHeader.biClrUsed = 0;
m_pInfo->bmiHeader.biPlanes = 1;
m_pInfo->bmiHeader.biSizeImage = 0;
m_pBits = NULL;
m_lWidth = 0;
m_lHeight = 0;
}
~CDIB()
{
free(m_pInfo);
m_pInfo = NULL;
if (NULL != m_hBitmap)
DeleteObject(m_hBitmap);
if (m_hSection != NULL)
CloseHandle(m_hSection);
if (m_hFile != NULL)
CloseHandle(m_hFile);
}
public:
BOOL Create(LONG lWidth, LONG lHeight, double dDPIX = 0, double dDPIY = 0)
{
m_lWidth = lWidth;
m_lHeight = lHeight;
m_pInfo->bmiHeader.biWidth = m_lWidth;
m_pInfo->bmiHeader.biHeight = m_lHeight;
if (dDPIX > 1 && dDPIY > 1)
{
m_pInfo->bmiHeader.biXPelsPerMeter = (LONG)(dDPIX / 0.0254);
m_pInfo->bmiHeader.biYPelsPerMeter = (LONG)(dDPIY / 0.0254);
}
m_hBitmap = ::CreateDIBSection(NULL, m_pInfo, DIB_RGB_COLORS, (VOID**)&m_pBits, NULL, 0);
DWORD dwError = GetLastError();
if (NULL == m_hBitmap)
{
CString strTempPath;
if (::GetTempPath(_MAX_PATH, strTempPath.GetBuffer(_MAX_PATH)) != 0)
strTempPath.ReleaseBuffer();
else
strTempPath = _T(".");
CString strTempFile;
if (::GetTempFileName(strTempPath, _T("dib"), 0, strTempFile.GetBuffer(_MAX_PATH)) != 0)
{
DWORD nLineLength = static_cast<DWORD>(ceil((double)(1.0 * m_lWidth * 32 / 8.0)));
while ((nLineLength % 4) != 0)
++nLineLength;
DWORD nBitsSize = nLineLength * m_lHeight;
// Try to create a mapped file section
m_hFile = ::CreateFile(strTempFile, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE)
{
m_hSection = ::CreateFileMapping(m_hFile, NULL,
PAGE_READWRITE, 0, nBitsSize, NULL);
if (m_hSection != NULL)
{
m_hBitmap = ::CreateDIBSection(NULL, m_pInfo, DIB_RGB_COLORS,
(VOID**)&m_pBits, m_hSection, 0);
}
}
if (NULL == m_hBitmap)
{
if (m_hSection != NULL)
::CloseHandle(m_hSection);
if (m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE)
::CloseHandle(m_hFile);
m_hSection = NULL;
m_hFile = NULL;
}
}
}
return (NULL != m_hBitmap);
}
void Draw(CPainter* pPainter, CDoubleRect& oRectDraw)
{
if (NULL == m_hBitmap)
return;
LONG lDrawWidth = (LONG)oRectDraw.GetWidth();
LONG lDrawHeight = (LONG)oRectDraw.GetHeight();
if ((lDrawWidth == m_lWidth) && (lDrawHeight == m_lHeight))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LONG leftBuffer = 0;
LONG leftDisplay = (LONG)oRectDraw.left;
if (leftDisplay < 0)
{
leftBuffer = -leftDisplay;
leftDisplay = 0;
}
LONG topBuffer = 0;
LONG topDisplay = (LONG)oRectDraw.top;
if (topDisplay < 0)
{
topBuffer = -topDisplay;
topDisplay = 0;
}
LONG bottomDisplay = min((LONG)oRectDraw.bottom, pPainter->m_lDisplayHeight - 1);
LONG rightDisplay = min((LONG)oRectDraw.right, pPainter->m_lDisplayWidth - 1);
HDC memdc = CreateCompatibleDC(pPainter->m_hMemDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, m_hBitmap);
BitBlt(pPainter->m_hMemDC, leftDisplay, topDisplay, rightDisplay - leftDisplay + 1, bottomDisplay - topDisplay + 1,
memdc, leftBuffer, topBuffer, SRCCOPY);
DeleteObject(hOldBitmap);
DeleteDC(memdc);
//SelectObject(pPainter->m_hMemDC, hOldBitmap);
//DeleteObject(hOldBitmap);
}
else
{
SetStretchBltMode(pPainter->m_hMemDC, COLORONCOLOR);
StretchDIBits(pPainter->m_hMemDC, (LONG)oRectDraw.left, (LONG)oRectDraw.top, (LONG)oRectDraw.GetWidth(), (LONG)oRectDraw.GetHeight(),
0, 0, m_lWidth, m_lHeight, m_pBits, m_pInfo, DIB_RGB_COLORS, SRCCOPY);
}
}
void Draw2(CPainter* pPainter, CDoubleRect& oRectDraw)
{
if (NULL == m_hBitmap)
return;
LONG lDrawWidth = (LONG)oRectDraw.GetWidth();
LONG lDrawHeight = (LONG)oRectDraw.GetHeight();
if ((lDrawWidth == m_lWidth) && (lDrawHeight == m_lHeight))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LONG leftBuffer = 0;
LONG leftDisplay = (LONG)oRectDraw.left;
if (leftDisplay < 0)
{
leftBuffer = -leftDisplay;
leftDisplay = 0;
}
LONG topBuffer = 0;
LONG topDisplay = (LONG)oRectDraw.top;
if (topDisplay < 0)
{
topBuffer = -topDisplay;
topDisplay = 0;
}
LONG bottomDisplay = min((LONG)oRectDraw.bottom, pPainter->m_lDisplayHeight - 1);
LONG rightDisplay = min((LONG)oRectDraw.right, pPainter->m_lDisplayWidth - 1);
HDC memdc = CreateCompatibleDC(pPainter->m_hDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, m_hBitmap);
BitBlt(pPainter->m_hDC, leftDisplay, topDisplay, rightDisplay - leftDisplay + 1, bottomDisplay - topDisplay + 1,
memdc, leftBuffer, topBuffer, SRCCOPY);
DeleteObject(hOldBitmap);
DeleteDC(memdc);
//SelectObject(pPainter->m_hMemDC, hOldBitmap);
//DeleteObject(hOldBitmap);
}
else
{
SetStretchBltMode(pPainter->m_hDC, COLORONCOLOR);
StretchDIBits(pPainter->m_hDC, (LONG)oRectDraw.left, (LONG)oRectDraw.top, (LONG)oRectDraw.GetWidth(), (LONG)oRectDraw.GetHeight(),
0, 0, m_lWidth, m_lHeight, m_pBits, m_pInfo, DIB_RGB_COLORS, SRCCOPY);
}
}
void Draw3(CPainter* pPainter, CDoubleRect& oRectDraw)
{
if (NULL == m_hBitmap)
return;
LONG lDrawWidth = (LONG)oRectDraw.GetWidth();
LONG lDrawHeight = (LONG)oRectDraw.GetHeight();
SetDIBitsToDevice(pPainter->m_hDC, (LONG)oRectDraw.left, (LONG)oRectDraw.top, m_lWidth, m_lHeight,
0, 0, 0, m_lHeight, m_pBits, m_pInfo, DIB_RGB_COLORS);
return;
if ((lDrawWidth == m_lWidth) && (lDrawHeight == m_lHeight))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LONG leftBuffer = 0;
LONG leftDisplay = (LONG)oRectDraw.left;
if (leftDisplay < 0)
{
leftBuffer = -leftDisplay;
leftDisplay = 0;
}
LONG topBuffer = 0;
LONG topDisplay = (LONG)oRectDraw.top;
if (topDisplay < 0)
{
topBuffer = -topDisplay;
topDisplay = 0;
}
LONG bottomDisplay = min((LONG)oRectDraw.bottom, pPainter->m_lDisplayHeight - 1);
LONG rightDisplay = min((LONG)oRectDraw.right, pPainter->m_lDisplayWidth - 1);
HDC memdc = CreateCompatibleDC(pPainter->m_hDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(memdc, m_hBitmap);
BitBlt(pPainter->m_hDC, leftDisplay, topDisplay, m_lWidth, m_lHeight,
memdc, leftBuffer, topBuffer, SRCCOPY);
DeleteObject(hOldBitmap);
DeleteDC(memdc);
//SelectObject(pPainter->m_hMemDC, hOldBitmap);
//DeleteObject(hOldBitmap);
}
else
{
SetStretchBltMode(pPainter->m_hDC, COLORONCOLOR);
StretchDIBits(pPainter->m_hDC, (LONG)oRectDraw.left, (LONG)oRectDraw.top, (LONG)oRectDraw.GetWidth(), (LONG)oRectDraw.GetHeight(),
0, 0, m_lWidth, m_lHeight, m_pBits, m_pInfo, DIB_RGB_COLORS, SRCCOPY);
}
}
};
}