CBitmapDraw.h
- #pragma once
- #include
- #include
-
- #define COLOR_RGB_TO_BGR(_rgb) ( (_rgb & 0xFF) << 16) | (_rgb & 0x00FF00) | ( (_rgb >> 16) & 0xFF)
-
- typedef struct _BITMAP_DRAW_DATA
- {
- BITMAPINFO binfo = { 0 }; //位图原始信息
- HBITMAP hBitmap = nullptr; //位图句柄
- LONG width = 0; //位图宽度
- LONG height = 0; //位图高度
- LPDWORD lpBits = nullptr; //位图全部数据缓冲 宽度 * 高度 * sizeof(DWORD)
- LPDWORD lpLineBuf = nullptr; //位图单行数据缓冲 宽度 * sizeof(DWORD)
-
- _BITMAP_DRAW_DATA(const _BITMAP_DRAW_DATA&) = delete;
-
- _BITMAP_DRAW_DATA()
- {
- ZeroMemory(this, sizeof(_BITMAP_DRAW_DATA));
- }
-
- ~_BITMAP_DRAW_DATA()
- {
- this->Release();
- }
-
- _BITMAP_DRAW_DATA(_BITMAP_DRAW_DATA&& r) noexcept
- {
- this->binfo = r.binfo;
- this->hBitmap = r.hBitmap;
- this->width = r.width;
- this->height = r.height;
- this->lpBits = r.lpBits;
- this->lpLineBuf = r.lpLineBuf;
-
- *this = std::move(r);
- }
-
- _BITMAP_DRAW_DATA operator = (const _BITMAP_DRAW_DATA&) = delete;
- _BITMAP_DRAW_DATA& operator = (_BITMAP_DRAW_DATA&& r) noexcept
- {
- this->binfo = r.binfo;
- this->hBitmap = r.hBitmap;
- this->width = r.width;
- this->height = r.height;
- this->lpBits = r.lpBits;
- this->lpLineBuf = r.lpLineBuf;
-
- r.lpBits = nullptr;
- r.lpLineBuf = nullptr;
- r.hBitmap = nullptr;
-
- return *this;
- }
-
- void Release()
- {
- if (nullptr != lpBits)
- {
- delete[] lpBits;
- lpBits = nullptr;
- }
- if (nullptr != lpLineBuf)
- {
- delete[] lpLineBuf;
- lpLineBuf = nullptr;
- }
-
- ZeroMemory(this, sizeof(_BITMAP_DRAW_DATA));
- }
- }BITMAP_DRAW_DATA, * PBITMAP_DRAW_DATA;
-
- class CBitmapDraw
- {
- public:
-
- CBitmapDraw(HDC hdc);
-
- ~CBitmapDraw();
-
- //获取位图宽度
- LONG GetWidth() const;
-
- //获取位图高度
- LONG GetHeight() const;
-
- //获取位图左上坐标
- POINT GetLeftTop() const;
-
- //获取位图右下坐标
- POINT GetRightBottom() const;
-
- //准备绘制
- bool BeginDraw();
-
- //结束绘制
- bool EndDraw();
-
- //绘制矩形边框
- void DrawRect(POINT ptLT, POINT ptRB, DWORD dwColor, bool bDotMode = false);
-
- //绘制线条
- void DrawLine(POINT ptLT, POINT ptRB, DWORD dwColor, bool bDotMode = false);
-
- //绘制圆形
- void DrawCircle(POINT ptLT, POINT ptRB, DWORD dwColor, bool bDotMode = false);
-
- //绘制网格
- void DrawGrid(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor, LONG xCount = 1, LONG yCount = 1, bool bDotMode = false);
-
- //填充网格
- void FillGrid(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor, LONG xCount = 1, LONG yCount = 1, POINT pt = { 0, 0 });
-
- //填充矩形区域
- void FillRect(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor);
-
- //限制坐标
- void LimitPiont(POINT& ptLT, POINT& ptRB);
-
- public:
-
- //调节起始坐标点, 确保起始点坐标在终止坐标的左上方
- static void AdjustPiont(POINT& ptLT, POINT& ptRB);
-
- //网格命中测试
- static bool GridHitTest(POINT ptLT, POINT ptRB, DWORD xCount, DWORD yCount, POINT ptCheck, POINT& ptOut);
-
- private:
-
- BITMAP_DRAW_DATA m_DrawData; //绘制数据
- HDC m_hDC = nullptr; //DC句柄
- };
-
CBitmapDraw.cpp
- #include "CBitmapDraw.h"
- #include
- #include
- #include
-
- #pragma intrinsic(memcpy)
-
- CBitmapDraw::CBitmapDraw(HDC hdc)
- {
- if (nullptr == hdc)
- {
- return;
- }
-
- do
- {
- m_hDC = hdc;
- int nScanlines = 0;
-
- //获取位图句柄
- m_DrawData.hBitmap = (HBITMAP)::GetCurrentObject(hdc, OBJ_BITMAP);
- if (nullptr == m_DrawData.hBitmap)
- {
- break;
- }
-
- //获取位图信息
- m_DrawData.binfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- nScanlines = ::GetDIBits(hdc, m_DrawData.hBitmap, 0, 0, nullptr, &m_DrawData.binfo, DIB_RGB_COLORS);
- if (0 == nScanlines)
- {
- break;
- }
-
- m_DrawData.binfo.bmiHeader.biPlanes = 1;
- m_DrawData.binfo.bmiHeader.biBitCount = 32;
-
- //取得位图尺寸, 分配位图数据缓冲
- m_DrawData.width = m_DrawData.binfo.bmiHeader.biWidth;
- m_DrawData.height = ::abs(m_DrawData.binfo.bmiHeader.biHeight);
-
- //高度方向矫正
- m_DrawData.binfo.bmiHeader.biCompression = BI_RGB;
- if (m_DrawData.binfo.bmiHeader.biHeight > 0)
- {
- m_DrawData.binfo.bmiHeader.biHeight = 0 - m_DrawData.binfo.bmiHeader.biHeight;
- }
-
- m_DrawData.binfo.bmiHeader.biCompression = BI_RGB;
-
- } while (false);
- }
-
- CBitmapDraw::~CBitmapDraw()
- {
- m_DrawData.Release();
- }
-
- LONG CBitmapDraw::GetWidth() const
- {
- return m_DrawData.width;
- }
-
- LONG CBitmapDraw::GetHeight() const
- {
- return m_DrawData.height;
- }
-
- POINT CBitmapDraw::GetLeftTop() const
- {
- return {0, 0};
- }
-
- POINT CBitmapDraw::GetRightBottom() const
- {
- return { m_DrawData.width - 1, m_DrawData.height - 1 };
- }
-
- bool CBitmapDraw::BeginDraw()
- {
- if (nullptr == m_hDC)
- {
- return false;
- }
-
- bool bRes = false;
- do
- {
- m_DrawData.Release();
-
- //获取位图句柄
- m_DrawData.hBitmap = (HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP);
- if (nullptr == m_DrawData.hBitmap)
- {
- break;
- }
-
- //获取位图信息
- m_DrawData.binfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- if (0 == ::GetDIBits(m_hDC, m_DrawData.hBitmap, 0, 0, nullptr, &m_DrawData.binfo, DIB_RGB_COLORS))
- {
- break;
- }
-
- m_DrawData.binfo.bmiHeader.biPlanes = 1;
- m_DrawData.binfo.bmiHeader.biBitCount = 32;
-
- //取得位图尺寸, 分配位图数据缓冲
- m_DrawData.width = m_DrawData.binfo.bmiHeader.biWidth;
- m_DrawData.height = ::abs(m_DrawData.binfo.bmiHeader.biHeight);
- m_DrawData.lpBits = new (std::nothrow) DWORD[m_DrawData.width * m_DrawData.height];
- if (nullptr == m_DrawData.lpBits)
- {
- break;
- }
-
- memset(m_DrawData.lpBits, 0, (m_DrawData.width * m_DrawData.height) * sizeof(DWORD));
-
- //分配单行缓冲
- m_DrawData.lpLineBuf = new (std::nothrow) DWORD[m_DrawData.width];
- if (nullptr == m_DrawData.lpLineBuf)
- {
- break;
- }
- memset(m_DrawData.lpLineBuf, 0, m_DrawData.width * sizeof(DWORD));
-
- //高度方向矫正
- m_DrawData.binfo.bmiHeader.biCompression = BI_RGB;
- if (m_DrawData.binfo.bmiHeader.biHeight > 0)
- {
- m_DrawData.binfo.bmiHeader.biHeight = 0 - m_DrawData.binfo.bmiHeader.biHeight;
- }
-
- //取得位图数据
- int nScanlines = ::GetDIBits(m_hDC, m_DrawData.hBitmap, 0, m_DrawData.height, m_DrawData.lpBits, &m_DrawData.binfo, DIB_RGB_COLORS);
- if (0 == nScanlines)
- {
- break;
- }
-
- m_DrawData.binfo.bmiHeader.biCompression = BI_RGB;
-
- bRes = true;
-
- } while (false);
-
- return bRes;
- }
-
- bool CBitmapDraw::EndDraw()
- {
- if (nullptr == m_DrawData.lpBits)
- {
- return false;
- }
-
- if (m_DrawData.lpBits)
- {
- //设置兼容位图中的像素。
- int nScanlines = ::SetDIBits(m_hDC, m_DrawData.hBitmap, 0, m_DrawData.height, m_DrawData.lpBits, &m_DrawData.binfo, DIB_RGB_COLORS);
- if (0 != nScanlines)
- {
- return true;
- }
- }
-
- return false;
- }
-
- void CBitmapDraw::LimitPiont(POINT& ptLT, POINT& ptRB)
- {
- LONG nWidth = m_DrawData.width;
- LONG nHeight = m_DrawData.height;
-
- //起点坐标限制
- if (ptLT.x < 0) ptLT.x = 0;
- if (ptLT.y < 0) ptLT.y = 0;
- if (ptLT.x > nWidth - 1) ptLT.x = nWidth - 1;
- if (ptLT.y > nHeight - 1) ptLT.y = nHeight - 1;
-
- //终点坐标限制
- if (ptRB.x < 0) ptRB.x = 0;
- if (ptRB.y < 0) ptRB.y = 0;
- if (ptRB.x > nWidth - 1) ptRB.x = nWidth - 1;
- if (ptRB.y > nHeight - 1) ptRB.y = nHeight - 1;
- }
-
- void CBitmapDraw::AdjustPiont(POINT& ptLT, POINT& ptRB)
- {
- LONG x0 = ptLT.x < ptRB.x ? ptLT.x : ptRB.x;
- LONG y0 = ptLT.y < ptRB.y ? ptLT.y : ptRB.y;
- LONG x1 = ptLT.x > ptRB.x ? ptLT.x : ptRB.x;
- LONG y1 = ptLT.y > ptRB.y ? ptLT.y : ptRB.y;
- ptLT = { x0 , y0 };
- ptRB = { x1 , y1 };
- }
- bool CBitmapDraw::GridHitTest(POINT ptLT, POINT ptRB, DWORD xCount, DWORD yCount, POINT ptCheck, POINT& ptOut)
- {
- //调节限制位置
- (void)AdjustPiont(ptLT, ptRB);
-
- //计算绘制区域宽高, 单行线条字节长度
- int nDrawWidth = ptRB.x - ptLT.x + 1;
- int nDrawHeight = ptRB.y - ptLT.y + 1;
-
- //格子数量限定
- if (xCount < 1) xCount = 1;
- if (yCount < 1) yCount = 1;
-
- //计算格子宽度
- int xGridWidth = nDrawWidth / xCount;
- int yGridHeight = nDrawHeight / yCount;
-
- //检查是否位于指定区域内(包含边框)
- if (!((ptCheck.x >= ptLT.x && ptCheck.x <= ptRB.x) && (ptCheck.y >= ptLT.y && ptCheck.y <= ptRB.y)))
- {
- return false;
- }
-
- ptOut.x = (ptCheck.x - ptLT.x) / xGridWidth;
- ptOut.y = (ptCheck.y - ptLT.y) / yGridHeight;
-
- return true;
- }
-
- void CBitmapDraw::DrawGrid(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor, LONG xCount/* = 1*/, LONG yCount/* = 1*/, bool bDotMode/* = false*/)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LPDWORD lpLineBuf = m_DrawData.lpLineBuf;
- LONG nWidth = m_DrawData.width;
- LONG nHeight = m_DrawData.height;
-
- //调节限制位置
- (void)AdjustPiont(ptSrcLT, ptSrcRB);
-
- //填充单行颜色
- if (lpLineBuf[0] != dwColor)
- {
- LPDWORD lpBuf = lpLineBuf;
- for (int i = 0; i < nWidth; i++)
- {
- *lpBuf++ = dwColor;
- }
- }
-
- //计算绘制区域宽高, 单行线条字节长度
- int nDrawWidth = ptSrcRB.x - ptSrcLT.x + 1;
- int nDrawHeight = ptSrcRB.y - ptSrcLT.y + 1;
-
- //格子数量限定
- if (xCount < 1) xCount = 1;
- if (yCount < 1) yCount = 1;
-
- //计算格子宽度
- int xGridSize = nDrawWidth / xCount;
- int yGridSize = nDrawHeight / yCount;
-
- LPDWORD lpData = nullptr;
-
- LONG nLineXBegin = ptSrcLT.x;
- LONG nLineXEnd = ptSrcRB.x;
- LONG nLineYBegin = ptSrcLT.y;
- LONG nLineYEnd = ptSrcRB.y;
- LONG nLineXSize = 0;
-
- if (nLineXBegin < 0) nLineXBegin = 0;
- if (nLineXEnd >= nWidth) nLineXEnd = nWidth - 1;
- if (nLineYBegin < 0) nLineYBegin = 0;
- if (nLineYEnd >= nHeight) nLineYEnd = nHeight - 1;
- nLineXSize = (nLineXEnd - nLineXBegin) * sizeof(DWORD);
-
- //左边竖线
- {
- if (bDotMode)
- {
- int nIndex = 0;
- LONG nCount = 0;
- for (LONG i = ptSrcLT.x; i < ptSrcRB.x && nCount < xCount; i += xGridSize, nCount++)
- {
- if (i >= 0 && i < nWidth)
- {
- lpData = lpBits + nLineYBegin * nWidth + i;
- for (LONG j = nLineYBegin; j < nLineYEnd; j++)
- {
- if (nIndex & 0x01)
- {
- *lpData = dwColor;
- }
- lpData += nWidth;
- nIndex++;
- }
- }
- }
- }
- else
- {
- LONG nCount = 0;
- for (LONG i = ptSrcLT.x; i < ptSrcRB.x && nCount < xCount; i += xGridSize, nCount++)
- {
- if (i >= 0 && i < nWidth)
- {
- lpData = lpBits + nLineYBegin * nWidth + i;
- for (LONG j = nLineYBegin; j < nLineYEnd; j++)
- {
- *lpData = dwColor;
- lpData += nWidth;
- }
- }
- }
- }
- }
-
- //顶部横线
- {
- if (bDotMode)
- {
- LONG nCount = 0;
- int nSize = nLineXEnd - nLineXBegin;
- for (LONG i = ptSrcLT.y; i < ptSrcRB.y && nCount < yCount; i += yGridSize, nCount++)
- {
- if (i >= 0 && i < nHeight)
- {
- lpData = lpBits + i * nWidth + nLineXBegin;
-
- int nIndex = 0;
- for (int j = 0; j < nSize; j++)
- {
- if (nIndex & 0x01)
- {
- lpData[j] = dwColor;
- }
- nIndex++;
- }
-
- }
- }
- }
- else
- {
- LONG nCount = 0;
- for (LONG i = ptSrcLT.y; i < ptSrcRB.y && nCount < yCount; i += yGridSize, nCount++)
- {
- if (i >= 0 && i < nHeight)
- {
- lpData = lpBits + i * nWidth + nLineXBegin;
- ::memcpy_s(lpData, nLineXSize, lpLineBuf, nLineXSize);
- }
- }
- }
- }
-
- //右边竖线
- if (bDotMode)
- {
- if (ptSrcRB.x >= 0 && ptSrcRB.x < nWidth)
- {
- int nIndex = 0;
- lpData = lpBits + nLineYBegin * nWidth + ptSrcRB.x;
- for (LONG i = nLineYBegin; i <= nLineYEnd; i++)
- {
- if (nIndex & 0x01)
- {
- *lpData = dwColor;
- }
-
- lpData += nWidth;
- nIndex++;
- }
- }
- }
- else
- {
- if (ptSrcRB.x >= 0 && ptSrcRB.x < nWidth)
- {
- lpData = lpBits + nLineYBegin * nWidth + ptSrcRB.x;
- for (LONG i = nLineYBegin; i <= nLineYEnd; i++)
- {
- *lpData = dwColor;
- lpData += nWidth;
- }
- }
- }
-
- //底部横线
- if (ptSrcRB.y >= 0 && ptSrcRB.y < nHeight)
- {
- lpData = lpBits + nLineYEnd * nWidth + nLineXBegin;
- if (bDotMode)
- {
- int nIndex = 0;
- int nSize = nLineXEnd - nLineXBegin;
- for (int i = 0; i < nSize; i++)
- {
- if (nIndex & 0x01)
- {
- lpData[i] = dwColor;
- }
- nIndex++;
- }
- }
- else
- {
- ::memcpy_s(lpData, nLineXSize, lpLineBuf, nLineXSize);
- }
- }
- }
-
- void CBitmapDraw::FillGrid(POINT ptLT, POINT ptRB, DWORD dwColor, LONG xCount/* = 1*/, LONG yCount/* = 1*/, POINT pt/* = { 0, 0 }*/)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LPDWORD lpLineBuf = m_DrawData.lpLineBuf;
- LONG nWidth = m_DrawData.width;
-
- //调节限制位置
- (void)AdjustPiont(ptLT, ptRB);
- (void)LimitPiont(ptLT, ptRB);
-
- //填充单行颜色
- if (lpLineBuf[0] != dwColor)
- {
- LPDWORD lpBuf = lpLineBuf;
- for (int i = 0; i < nWidth; i++)
- {
- *lpBuf++ = dwColor;
- }
- }
-
- //计算绘制区域宽高, 单行线条字节长度
- int nDrawWidth = ptRB.x - ptLT.x + 1;
- int nDrawHeight = ptRB.y - ptLT.y + 1;
-
- //格子数量限定
- if (xCount < 1) xCount = 1;
- if (yCount < 1) yCount = 1;
-
- //限定目标格子坐标
- if (pt.x < 0) pt.x = 0;
- if (pt.y < 0) pt.y = 0;
- if (pt.x >= xCount) pt.x = xCount - 1;
- if (pt.y >= yCount) pt.y = yCount - 1;
-
- //计算格子宽度
- int xGridWidth = nDrawWidth / xCount;
- int yGridHeight = nDrawHeight / yCount;
- int xGridWidthSize = xGridWidth * sizeof(DWORD);
-
- //填充单行颜色
- if (lpLineBuf[0] != dwColor)
- {
- LPDWORD lpBuf = lpLineBuf;
- for (int i = 0; i < nWidth; i++)
- {
- *lpBuf++ = dwColor;
- }
- }
-
- //填充
- LPDWORD lpData = lpBits + (ptLT.y + pt.y * yGridHeight) * nWidth + ptLT.x + pt.x * xGridWidth;
- for (int i = 0; i < yGridHeight; i++)
- {
- memcpy_s(lpData, xGridWidthSize, lpLineBuf, xGridWidthSize);
- lpData += nWidth;
- }
- }
-
- void CBitmapDraw::FillRect(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LPDWORD lpLineBuf = m_DrawData.lpLineBuf;
- LONG nWidth = m_DrawData.width;
-
- POINT ptLT = ptSrcLT;
- POINT ptRB = ptSrcRB;
-
- //调节限制位置
- (void)AdjustPiont(ptLT, ptRB);
- (void)LimitPiont(ptLT, ptRB);
-
- //填充单行颜色
- if (lpLineBuf[0] != dwColor)
- {
- LPDWORD lpBuf = lpLineBuf;
- for (int i = 0; i < nWidth; i++)
- {
- *lpBuf++ = dwColor;
- }
- }
-
- //计算绘制区域宽高, 单行线条字节长度
- int nDrawWidth = ptRB.x - ptLT.x + 1;
- int nDrawHeight = ptRB.y - ptLT.y + 1;
- int nDrawLineSize = nDrawWidth * sizeof(DWORD);
-
- LPDWORD lpData = lpBits + (ptLT.y) * nWidth + ptLT.x;
- for (int i = 0; i < nDrawHeight; i++)
- {
- memcpy_s(lpData, nDrawLineSize, lpLineBuf, nDrawLineSize);
- lpData += nWidth;
- }
- }
-
- void CBitmapDraw::DrawRect(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor, bool bDotMode/* = true*/)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LPDWORD lpLineBuf = m_DrawData.lpLineBuf;
- LONG nWidth = m_DrawData.width;
- LONG nHeight = m_DrawData.height;
-
- //调节限制位置
- (void)AdjustPiont(ptSrcLT, ptSrcRB);
-
- //填充单行颜色
- if (lpLineBuf[0] != dwColor)
- {
- LPDWORD lpBuf = lpLineBuf;
- for (int i = 0; i < nWidth; i++)
- {
- *lpBuf++ = dwColor;
- }
- }
-
- LONG nLineXBegin = ptSrcLT.x;
- LONG nLineXEnd = ptSrcRB.x;
- LONG nLineYBegin = ptSrcLT.y;
- LONG nLineYEnd = ptSrcRB.y;
- LONG nLineXSize = 0;
-
- if (nLineXBegin < 0) nLineXBegin = 0;
- if (nLineXEnd >= nWidth) nLineXEnd = nWidth - 1;
- if (nLineYBegin < 0) nLineYBegin = 0;
- if (nLineYEnd >= nHeight) nLineYEnd = nHeight - 1;
- nLineXSize = (nLineXEnd - nLineXBegin) * sizeof(DWORD);
-
- LPDWORD lpData = nullptr;
-
- //顶部横线
- if (ptSrcLT.y >= 0 && ptSrcLT.y < nHeight && nLineXSize > 0)
- {
- lpData = lpBits + nLineYBegin * nWidth + nLineXBegin;
-
- if (bDotMode)
- {
- int nIndex = 0;
- int nSize = nLineXEnd - nLineXBegin;
- for (int i = 0; i < nSize; i++)
- {
- if (nIndex & 0x01)
- {
- lpData[i] = dwColor;
- }
- nIndex++;
- }
- }
- else
- {
- ::memcpy_s(lpData, nLineXSize, lpLineBuf, nLineXSize);
- }
-
- }
-
- //底部横线
- if (ptSrcRB.y >= 0 && ptSrcRB.y < nHeight && nLineXSize > 0)
- {
- lpData = lpBits + nLineYEnd * nWidth + nLineXBegin;
- if (bDotMode)
- {
- int nIndex = 0;
- int nSize = nLineXEnd - nLineXBegin;
- for (int i = 0; i < nSize; i++)
- {
- if (nIndex & 0x01)
- {
- lpData[i] = dwColor;
- }
- nIndex++;
- }
- }
- else
- {
- ::memcpy_s(lpData, nLineXSize, lpLineBuf, nLineXSize);
- }
- }
-
- //左边竖线
- if (ptSrcLT.x >= 0 && ptSrcLT.x < nWidth)
- {
- lpData = lpBits + nLineYBegin * nWidth + nLineXBegin;
-
- if (bDotMode)
- {
- int nIndex = 0;
- for (LONG i = nLineYBegin; i < nLineYEnd; i++)
- {
- if (nIndex & 0x01)
- {
- *lpData = dwColor;
- }
- lpData += nWidth;
- nIndex++;
- }
- }
- else
- {
- for (LONG i = nLineYBegin; i < nLineYEnd; i++)
- {
- *lpData = dwColor;
- lpData += nWidth;
- }
- }
- }
-
- //右边竖线
- if (ptSrcRB.x >= 0 && ptSrcRB.x < nWidth)
- {
- lpData = lpBits + nLineYBegin * nWidth + nLineXEnd;
-
- if (bDotMode)
- {
- int nIndex = 0;
- for (LONG i = nLineYBegin; i <= nLineYEnd; i++)
- {
- if (nIndex & 0x01)
- {
- *lpData = dwColor;
- }
- lpData += nWidth;
- nIndex++;
- }
- }
- else
- {
- for (LONG i = nLineYBegin; i <= nLineYEnd; i++)
- {
- *lpData = dwColor;
- lpData += nWidth;
- }
- }
- }
- }
-
- void CBitmapDraw::DrawLine(POINT ptSrcLT, POINT ptSrcRB, DWORD dwColor, bool bDotMode/* = true*/)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LONG nWidth = m_DrawData.width;
- LONG nHeight = m_DrawData.height;
-
- POINT ptLT = ptSrcLT;
- POINT ptRB = ptSrcRB;
-
- //计算绘制区域内相交点
-
- /*{
- int x0 = ptLT.x;
- int y0 = ptLT.y;
- int x1 = ptRB.x;
- int y1 = ptRB.y;
- int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
- int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
- int erro = (dx > dy ? dx : -dy) / 2;
- do
- {
- lpBits[y0 * nWidth + x0] = dwColor;
- int e2 = erro;
- if (e2 > -dx)
- {
- erro -= dy;
- x0 += sx;
- }
- if (e2 < dy)
- {
- erro += dx;
- y0 += sy;
- }
- } while (x0 != x1 || y0 != y1);
- }*/
-
- //画任意斜率的直线(基于 Bresenham 算法)
-
- {
- int x1 = ptLT.x;
- int y1 = ptLT.y;
- int x2 = ptRB.x;
- int y2 = ptRB.y;
-
- int x = ptLT.x;
- int y = ptLT.y;
-
- int dx = ::abs(x2 - x1);
- int dy = ::abs(y2 - y1);
- int s1 = x2 > x1 ? 1 : -1;
- int s2 = y2 > y1 ? 1 : -1;
-
- bool interchange = false;// 默认不互换 dx、dy
- if (dy > dx)// 当斜率大于 1 时,dx、dy 互换
- {
- int temp = dx;
- dx = dy;
- dy = temp;
- interchange = true;
- }
-
- int p = 2 * dy - dx;
-
- if (!interchange)
- {
- if (bDotMode)
- {
- int nIndex = 0;
- for (int i = 0; i <= dx; i++)
- {
- if (y >= 0 && y < nHeight && x >= 0 && x < nWidth)
- {
- if (nIndex & 0x01)
- {
- lpBits[y * nWidth + x] = dwColor;
- }
- nIndex++;
- }
-
- if (p >= 0)
- {
- y += s2;
- p -= 2 * dx;
- }
-
- x += s1;// 当斜率 < 1 时,选取 x 为步长
- p += 2 * dy;
- }
- }
- else
- {
- for (int i = 0; i <= dx; i++)
- {
- if (y >= 0 && y < nHeight && x >= 0 && x < nWidth)
- {
- lpBits[y * nWidth + x] = dwColor;
- }
-
- if (p >= 0)
- {
- y += s2;
- p -= 2 * dx;
- }
-
- x += s1;// 当斜率 < 1 时,选取 x 为步长
- p += 2 * dy;
- }
- }
- }
- else
- {
- if (bDotMode)
- {
- int nIndex = 0;
- for (int i = 0; i <= dx; i++)
- {
- if (y >= 0 && y < nHeight && x >= 0 && x < nWidth)
- {
- if (nIndex & 0x01)
- {
- lpBits[y * nWidth + x] = dwColor;
- }
- nIndex++;
- }
-
- if (p >= 0)
- {
- x += s1;
- p -= 2 * dx;
- }
-
- y += s2;// 当斜率 > 1 时,选取 y 为步长
- p += 2 * dy;
- }
- }
- else
- {
- for (int i = 0; i <= dx; i++)
- {
- if (y >= 0 && y < nHeight && x >= 0 && x < nWidth)
- {
- lpBits[y * nWidth + x] = dwColor;
- }
-
- if (p >= 0)
- {
- x += s1;
- p -= 2 * dx;
- }
-
- y += s2;// 当斜率 > 1 时,选取 y 为步长
- p += 2 * dy;
- }
- }
- }
- }
- }
-
- void CBitmapDraw::DrawCircle(POINT ptLT, POINT ptRB, DWORD dwColor, bool bDotMode/* = true*/)
- {
- dwColor = COLOR_RGB_TO_BGR(dwColor);
- if (nullptr == m_DrawData.lpBits)
- {
- return;
- }
-
- LPDWORD lpBits = m_DrawData.lpBits;
- LONG nWidth = m_DrawData.width;
- LONG nHeight = m_DrawData.height;
-
- //调节限制位置
- (void)AdjustPiont(ptLT, ptRB);
-
- LONG nW = ptRB.x - ptLT.x;
- LONG nH = ptRB.y - ptLT.y;
-
- LONG r = (LONG)::sqrt((nW * nW) + (nH * nH)) / 2;
-
- LONG x = ptLT.x;
- LONG y = ptLT.y;
-
- x += nW / 2;
- y += nH / 2;
-
- {
- int xi;
- int yi;
- int di;
- di = 1 - r;
- xi = 0;
- yi = r;
- LONGLONG dwOffset = 0;
-
- int nXPox = 0;
- int nYPos = 0;
-
- if (bDotMode)
- {
- int nIndex = 0;
- while (yi >= xi)
- {
- //右下 1/4
- nXPox = y + yi;
- nYPos = x + xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- nXPox = y + xi;
- nYPos = x + yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- //左下 1/4
- nXPox = y + yi;
- nYPos = x - xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- nXPox = y + xi;
- nYPos = x - yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- //左上 1/4
- nXPox = y - yi;
- nYPos = x - xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- nXPox = y - xi;
- nYPos = x - yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- //右上 1/4
- nXPox = y - yi;
- nYPos = x + xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- nXPox = y - xi;
- nYPos = x + yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth && nIndex & 0x01) lpBits[dwOffset] = dwColor;
-
- if (di < 0)
- {
- di += 3 + (xi << 1);
- }
- else
- {
- di += 5 + ((xi - yi) << 1);
- yi--;
- }
- xi++;
- nIndex++;
- }
- }
- else
- {
- while (yi >= xi)
- {
- //右下 1/4
- nXPox = y + yi;
- nYPos = x + xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- nXPox = y + xi;
- nYPos = x + yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- //左下 1/4
- nXPox = y + yi;
- nYPos = x - xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- nXPox = y + xi;
- nYPos = x - yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- //左上 1/4
- nXPox = y - yi;
- nYPos = x - xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- nXPox = y - xi;
- nYPos = x - yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- //右上 1/4
- nXPox = y - yi;
- nYPos = x + xi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- nXPox = y - xi;
- nYPos = x + yi;
- dwOffset = nXPox * nWidth + nYPos;
- if (nXPox >= 0 && nXPox < nHeight && nYPos >= 0 && nYPos < nWidth) lpBits[dwOffset] = dwColor;
-
- if (di < 0)
- {
- di += 3 + (xi << 1);
- }
- else
- {
- di += 5 + ((xi - yi) << 1);
- yi--;
- }
- xi++;
- }
- }
- }
- }

CBitmapPaint: 位图操作绘制图形 1.绘制线条 2.绘制矩形边框 3.填充矩形区域 4.绘制圆形边框 5.绘制网格线条 并比较使用位图操作与使用GDI绘制的速度 (gitee.com)