📄 asl_bitmap.cpp
字号:
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Line()
// 功 能: 绘制直线
// 参 数: [cl] - 直线颜色
// [x1] - 起点x坐标
// [y1] - 起点y坐标
// [x2] - 终点x坐标
// [y2] - 终点y坐标
// [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Line(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
ASSERT(m_hBitmap != NULL);
HPEN hpen, hpenold;
// 按指定颜色设置画笔
hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
hpenold = (HPEN)SelectObject(m_hDC, hpen);
// 调用GDI函数画线
MoveToEx(m_hDC, x1, y1, (LPPOINT)NULL);
LineTo(m_hDC, x2, y2);
// 恢复原画笔
SelectObject(m_hDC, hpenold);
// 删除创建的画笔
DeleteObject(hpen);
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Rect()
// 功 能: 绘制矩形(仅边框)
// 参 数: [cl] - 颜色
// [x1] - 左上角x坐标
// [y1] - 左上角y坐标
// [x2] - 右下角x坐标
// [y2] - 右下角y坐标
// [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Rect(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
ASSERT(m_hBitmap != NULL);
HPEN hpen, hpenold;
// 按指定颜色设置画笔
hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
hpenold = (HPEN)SelectObject(m_hDC, hpen);
// 调用GDI函数画矩形
::Rectangle(m_hDC, x1, y1, x2, y2);
// 恢复原画笔
SelectObject(m_hDC, hpenold);
// 删除创建的画笔
DeleteObject(hpen);
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::FillRect()
// 功 能: 填充矩形
// 参 数: [color] - 颜色
// [x1] - 左上角x坐标
// [y1] - 左上角y坐标
// [x2] - 右下角x坐标
// [y2] - 右下角y坐标
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::FillRect(COLOR color, int x1, int y1, int x2, int y2)
{
ASSERT(m_hBitmap != NULL);
// 对目标矩形进行调整
RECT rc;
SetRect(&rc, x1, y1, x2, y2);
if (!_Clip(rc))
{
return;
}
const char *pdst = (char*)m_pData + m_nPitch * rc.top + rc.left * 2;
const int nWidth = rc.right - rc.left;
const int nHeight = rc.bottom - rc.top;
const int pad = m_nPitch - nWidth * 2;
if (nWidth <= 0 || nHeight <= 0)
{
return;
}
__asm
{
mov ax, color
mov edi, pdst
movd mm0, eax
mov ebx, nHeight
punpcklwd mm0, mm0
mov edx, pad
punpckldq mm0, mm0
mov esi, nWidth
mov ecx, esi
cld
align 4
_nextqword:
sub ecx, 4
jle _residual
movq [edi], mm0
add edi, 8
jmp _nextqword
_residual:
add ecx, 4
rep stosw
add edi, edx
mov ecx, esi
dec ebx
jnz _nextqword
emms
}
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Ellipse()
// 功 能: 绘制椭圆(仅边框)
// 参 数: [cl] - 颜色
// [x1] - 左上角x坐标
// [y1] - 左上角y坐标
// [x2] - 右下角x坐标
// [y2] - 右下角y坐标
// [size] - 线宽
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Ellipse(COLOR cl, int x1, int y1, int x2, int y2, int size)
{
ASSERT(m_hBitmap != NULL);
HPEN hpen, hpenold;
// 按指定颜色设置画笔
hpen = CreatePen(PS_SOLID, size, GetRGB32(cl));
hpenold = (HPEN)SelectObject(m_hDC, hpen);
// 调用GDI函数画椭圆
::Ellipse(m_hDC, x1, y1, x2, y2);
// 恢复原画笔
SelectObject(m_hDC, hpenold);
// 删除创建的画笔
DeleteObject(hpen);
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::FillEllipse()
// 功 能: 填充椭圆
// 参 数: [cl] - 颜色
// [x1] - 左上角x坐标
// [y1] - 左上角y坐标
// [x2] - 右下角x坐标
// [y2] - 右下角y坐标
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::FillEllipse(COLOR cl, int x1, int y1, int x2, int y2)
{
ASSERT(m_hBitmap != NULL);
HPEN hpen, hpenold;
HBRUSH hbrush, hbrushold;
// 按指定颜色设置画笔和画刷
hpen = CreatePen(PS_SOLID, 1, GetRGB32(cl));
hpenold = (HPEN)SelectObject(m_hDC, hpen);
hbrush = CreateSolidBrush(GetRGB32(cl));
hbrushold = (HBRUSH)SelectObject(m_hDC, hbrush);
// 调用GDI函数画椭圆
::Ellipse(m_hDC, x1, y1, x2, y2);
// 恢复原画笔、画刷
SelectObject(m_hDC, hpenold);
SelectObject(m_hDC, hbrushold);
// 删除创建的画笔、画刷
DeleteObject(hpen);
DeleteObject(hbrush);
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Filter()
// 功 能: 滤镜效果
// 参 数: [cl] - 滤镜颜色
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Filter(COLOR cl)
{
//int rmax = GetRed(cl);
//int gmax = GetGreen(cl);
//int bmax = GetBlue(cl);
//int r, g, b;
//for (int i = 0; i < m_nPitch/2 * m_nHeight; ++i)
//{
// r = GetRed(m_pData[i]);
// g = GetGreen(m_pData[i]);
// b = GetBlue(m_pData[i]);
// r = r > rmax ? rmax : r;
// g = g > gmax ? gmax : g;
// b = b > bmax ? bmax : b;
// m_pData[i] = RGB16(r, g, b);
//}
UINT count = m_nPitch * m_nHeight / 8;
COLOR *p = m_pData;
__asm
{
mov ecx, count
movd mm7, cl
punpcklwd mm7, mm7
punpckldq mm7, mm7
mov edi, p
align 4
_next:
movq mm0, [edi]
pand mm0, mm7
movq [edi], mm0
add edi, 8
loop _next
emms
}
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::ConvertGray()
// 功 能: 将位图灰度化
// 参 数: [void] - 无
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::ConvertGray(void)
{
int r, g, b, gray;
for (int i = 0; i < m_nPitch/2 * m_nHeight; ++i)
{
r = GetRed(m_pData[i]);
g = GetGreen(m_pData[i]);
b = GetBlue(m_pData[i]);
gray = (r * 3 + g * 6 + b) / 10;
m_pData[i] = RGB16(gray, gray, gray);
}
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::Mix()
// 功 能: 将位图与指定颜色按比例混合(可实现淡入淡出)
// 参 数: [cl] - 颜色
// [nAlpha] - 混合度 0 - 256
// [*rect] - 绘制区矩形, 为空时表示整张位图
// 返回值: [void] - 无
//-----------------------------------------------------------------------------
void ASLBitmap::Mix(COLOR cl, int nAlpha, const RECT &rc)
{
ASSERT(m_hBitmap != NULL);
RECT rect;
if (EqualRect(&rc, &DEFAULTRECT))
{
rect = m_rcClip;
}
else
{
rect = rc;
if (!_Clip(rect))
{
return;
}
}
int nWidth = rc.right - rc.left;
int nHeight = rc.bottom - rc.top;
if (nWidth <= 0 || nHeight <= 0)
{
return;
}
if (nAlpha < 0)
{
nAlpha = 0;
}
else if (nAlpha > 256)
{
nAlpha = 256;
}
if (nAlpha == 0)
{
return;
}
else if (nAlpha == 256)
{
FillRect(cl, rect.left, rect.top, rect.right, rect.bottom);
}
else
{
BYTE *pdst = (BYTE*)m_pData + m_nPitch * rect.top + rect.left * 2;
const __int64 alpha64 = Bit16To64(nAlpha >> 3);
const __int64 clr64 = Bit16To64(cl);
for (int i = 0; i < nHeight; ++i)
{
asmMix(pdst, nWidth, clr64, alpha64);
pdst += m_nPitch;
}
}
}
/******************************************************************************
* 私有函数函数
******************************************************************************/
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::_AdjustDrawPos()
// 功 能: 调整绘图位置
// 参 数: [&bmDest] - 目标位图
// [&xDest] - 目标x坐标
// [&yDest] - 目标y坐标
// [&rcSrc] - 源绘制区矩形
// 返回值: true - 需要绘制
// false - 超出范围, 无需绘制
//-----------------------------------------------------------------------------
bool ASLBitmap::_AdjustDrawPos(const ASLBitmap &bmDest, int &xDest, int &yDest,
RECT &rcSrc) const
{
if (!_Clip(rcSrc))
{
return false;
}
RECT rcDst, rcTmp;
rcDst.left = xDest;
rcDst.top = yDest;
rcDst.right = rcDst.left + (rcSrc.right - rcSrc.left);
rcDst.bottom = rcDst.top + (rcSrc.bottom - rcSrc.top);
rcTmp = rcDst;
if (!bmDest._Clip(rcTmp))
{
return false;
}
if (rcTmp.left > rcDst.left)
{
rcSrc.left += rcTmp.left - rcDst.left;
}
if (rcTmp.top > rcDst.top)
{
rcSrc.top += rcTmp.top - rcDst.top;
}
if (rcTmp.right < rcDst.right)
{
rcSrc.right += rcTmp.right - rcDst.right;
}
if (rcTmp.bottom < rcDst.bottom)
{
rcSrc.bottom += rcTmp.bottom - rcDst.bottom;
}
xDest = rcTmp.left;
yDest = rcTmp.top;
return true;
}
//-----------------------------------------------------------------------------
// 函数名: ASLBitmap::_Clip()
// 功 能: 将矩形按本位图裁剪矩形进行裁剪
// 参 数: [&rect] - 待裁剪矩形
// 返回值: true - 该矩形有效
// false - 该矩形无效
//-----------------------------------------------------------------------------
bool ASLBitmap::_Clip(RECT &rect) const
{
ASSERT(rect.right >= rect.left && rect.bottom > rect.top);
if (rect.left >= m_nWidth || rect.top >= m_nHeight
|| rect.bottom <= 0 || rect.right <= 0)
{
return false;
}
if (rect.left < 0)
{
rect.left = 0;
}
if (rect.top < 0)
{
rect.top = 0;
}
if (rect.right > m_nWidth)
{
rect.right = m_nWidth;
}
if (rect.bottom > m_nHeight)
{
rect.bottom = m_nHeight;
}
return true;
}
} // namespace ASL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -