📄 dc.cpp
字号:
#include "gos.h"
#include "dc.h"
#define DCE_PIXELX(x,y) s=x0+(x);b=y0+(y); \
rp.MoveTo(nAddr);rp.Offset(x,y); \
if(rc.PtInRect(s,b) && (nPS&(1<<(s&31))))rp.ROP(rp)
#define DCE_PIXELY(x,y) s=y0+(y);a=x0+(x); \
rp.MoveTo(nAddr);rp.Offset(x,y); \
if(rc.PtInRect(a,s) && (nPS&(1<<(s&31))))rp.ROP(rp)
CDC::CDC(void)
{
m_pBitmap=NULL;
m_pPalette=NULL;
m_pPen=NULL;
m_pBrush=NULL;
m_pFont=NULL;
m_nDrawMode=R2_COPYPEN;
m_nTextColor=0;
m_nBkColor=CLR_NONE;
}
void CDC::SetPixel(POINT pt,COLORREF clr)
{
if(clr==CLR_NONE)
return;
if(m_rclClip.PtInRect(pt))
{
CROP& rp=m_rop;
rp.MoveTo(pt.x-m_ptOrg.x,pt.y-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,clr);
rp.ROP(rp);
}
}
void CDC::FillSolidRect(LPCRECT pRect,COLORREF clr)
{
CROP &rp=m_rop;
DWORD nAddr;
int nLeft;
CRect rect(m_rclClip);
rect.IntersectRect(pRect);
if(rect.IsRectEmpty())
return;
if(clr==CLR_NONE)
return;
nAddr=rp.MoveTo(rect.left-m_ptOrg.x,rect.top-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,clr);
for(nLeft=rect.left;rect.top<rect.bottom;rect.top++)
{
for(;rect.left<rect.right;rect.left++)
{
rp.ROP(rp);
rp.StepCol();
}
nAddr=rp.StepRow(nAddr);
rect.left=nLeft;
}
}
void CDC::FillRect(LPCRECT pRect)
{
CROP &rp=m_rop;
int nLeft;
DWORD nAddr,nMask;
DWORD nBS=m_pBrush->m_nStyle;
CRect rect(m_rclClip);
rect.IntersectRect(pRect);
if(rect.IsRectEmpty())
return;
if(nBS==HS_NULL)
return;
nAddr=rp.MoveTo(rect.left-m_ptOrg.x,rect.top-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,m_pBrush->m_crColor);
for(nLeft=rect.left;rect.top<rect.bottom;rect.top++)
{
for(;rect.left<rect.right;rect.left++)
{
nMask=((rect.top&3)<<3)+(rect.left&7);
if(nBS & (1<<nMask))
rp.ROP(rp);
rp.StepCol();
}
nAddr=rp.StepRow(nAddr);
rect.left=nLeft;
}
}
void CDC::Polyline(PPOINT pPoints,int nCount)
{
for(;--nCount>0;)
{
PrvLine(pPoints[nCount],pPoints[nCount-1]);
}
}
void CDC::Polygon(PPOINT pPoints,int nCount)
{
int i,y,nMaxX,nMinX;
int nMaxY=MINLONG,nMinY=MAXLONG;
CRect r;
if(m_pBrush->m_nStyle!=HS_NULL)
{
for(i=nCount;i-->0;)
{
y=pPoints[i].y;
if(nMinY>y)nMinY=y;
if(nMaxY<y)nMaxY=y;
}
for(y=nMinY;y<=nMaxY;y++)
{
nMaxX=MINLONG,nMinX=MAXLONG;
for(i=nCount;--i>0;)
{
PrvPolygon(pPoints[i],pPoints[i-1],y,&nMinX,&nMaxX);
}
PrvPolygon(pPoints[0],pPoints[nCount-1],y,&nMinX,&nMaxX);
r.SetRect(nMinX,y,nMaxX+1,y+1);
FillRect(&r);
}
}
if(m_pPen->m_nStyle!=PS_NULL)
{
for(i=nCount;--i>0;)
{
PrvLine(pPoints[i],pPoints[i-1]);
}
PrvLine(pPoints[0],pPoints[nCount-1]);
}
}
void CDC::Ellipse(LPCRECT pRect)
{
CROP &rp=m_rop;
DWORD nAddr;
int x0,y0,x,y,a2,b2,a,b,xb2,ya2,sum,s;
int nPW=m_pPen->m_nWidth;
int nPS=m_pPen->m_nStyle;
CRect r(pRect);
CRect rc(m_rclClip);
rp.SetRopByPenColor(m_nDrawMode,m_pPen->m_crColor);
while(--nPW>=0)
{
if(r.right-r.left<2 || r.bottom-r.top<2)break;
r.right--;
r.bottom--;
if(m_pPen->m_nStyle!=PS_NULL)
{
x=r.left;
y=r.top;
a2=r.right;
b2=r.bottom;
a=(a2-x)>>1;
b=(b2-y)>>1;
x0=(x+a2)>>1;
y0=(y+b2)>>1;
a2=a*a;
b2=b*b;
nAddr=rp.MoveTo(x0-m_ptOrg.x,y0-m_ptOrg.y);
x=0;
y=b;
sum=0;
DCE_PIXELX(0,y);
DCE_PIXELX(0,-y);
for(;;)
{
xb2=b2*x<<1;
ya2=a2*y<<1;
if(xb2>ya2)break;
s=ya2-a2;
if(sum>(s>>1))
{
y--;
sum-=s;
}
else
{
x++;
sum+=xb2+b2;
}
DCE_PIXELX(x,y);
DCE_PIXELX(x,-y);
DCE_PIXELX(-x,y);
DCE_PIXELX(-x,-y);
}
x=a;
y=0;
sum=0;
DCE_PIXELY(x,0);
DCE_PIXELY(-x,0);
for(;;)
{
xb2=b2*x<<1;
ya2=a2*y<<1;
if(xb2<ya2)break;
s=xb2-b2;
if(sum>(s>>1))
{
x--;
sum-=s;
}
else
{
y++;
sum+=ya2+a2;
}
DCE_PIXELY(x,y);
DCE_PIXELY(x,-y);
DCE_PIXELY(-x,y);
DCE_PIXELY(-x,-y);
}
}
r.left++;
r.top++;
}
PrvFillEllipse(&r);
}
void CDC::Rectangle(LPCRECT pRect)
{
CRect r(pRect);
CPoint pt1,pt2;
int nPW=m_pPen->m_nWidth;
while(--nPW>=0)
{
r.right--;
r.bottom--;
if(r.top<=r.bottom)
PrvLineH(r.top,r.left,r.right-1);
if(r.top<r.bottom)
PrvLineH(r.bottom,r.left+1,r.right);
if(r.left<=r.right)
PrvLineV(r.left,r.top+1,r.bottom);
if(r.left<r.right)
PrvLineV(r.right,r.top,r.bottom-1);
r.left++;
r.top++;
}
if(m_pBrush->m_nStyle!=HS_SOLID)
FillRect(r);
else
FillSolidRect(r,m_pBrush->m_crColor);
}
void CDC::DrawRect(LPCRECT pRect,COLORREF crColor,int nPenStyle)
{
CRect r(pRect);
CPen pen(nPenStyle,1,crColor),*pOldPen=m_pPen;
r.DeflateRect(0,0,1,1);
if(r.IsRectEmpty())
return;
m_pPen=&pen;
PrvLineH(r.top,r.left,r.right-1);
PrvLineV(r.left,r.top+1,r.bottom-1);
PrvLineH(r.bottom,r.left,r.right);
PrvLineV(r.right,r.top,r.bottom-1);
m_pPen=pOldPen;
}
void CDC::Draw3dRect(LPCRECT pRect,COLORREF clrTopLeft,COLORREF clrBottomRight)
{
CRect r(pRect);
CPen pen,*pOldPen=m_pPen;
r.DeflateRect(0,0,1,1);
if(r.IsRectEmpty())
return;
m_pPen=&pen;
pen.CreatePen(PS_SOLID,1,clrTopLeft);
PrvLineH(r.top,r.left,r.right-1);
PrvLineV(r.left,r.top+1,r.bottom-1);
pen.CreatePen(PS_SOLID,1,clrBottomRight);
PrvLineH(r.bottom,r.left,r.right);
PrvLineV(r.right,r.top,r.bottom-1);
m_pPen=pOldPen;
}
void CDC::BitBlt(LPCRECT pDestRect,CBitmap* pBitmap,LPCRECT pSrcRect,DWORD nRop)
{
CSize sd1,sd2;
CRect r1,r2(pDestRect);
CROP &rp=m_rop,rpBmp;
//校正图片区域及目的区域
r1.SetRect(CPoint(0,0),pBitmap->GetSize());
if(pSrcRect)
r1.IntersectRect(pSrcRect);
if(r1.IsRectEmpty())
return;
sd1=r1.Size();
if(nRop & R2_ZOOM)
{
if(!(nRop&R2_ZOOMIN))
{
if(sd1.cy<r2.Height() && sd1.cx<r2.Width())
nRop &= ~R2_ZOOM;
}
if(!(nRop&R2_ZOOMOUT))
{
if(sd1.cy>r2.Height() || sd1.cx>r2.Width())
nRop &= ~R2_ZOOM;
}
if(nRop & R2_ZOOM)
{
sd2=sd1;
sd2.cx*=r2.Height();
sd2.cy*=r2.Width();
if(sd2.cx<sd2.cy)
{
sd2.cx/=sd1.cy;
if(nRop & R2_LEFT)
r2.right=r2.left+sd2.cx;
else if(nRop & R2_RIGHT)
r2.left=r2.right-sd2.cx;
else
{
r2.left=(r2.left+r2.right-sd2.cx)>>1;
r2.right=r2.left+sd2.cx;
}
}
else
{
sd2.cy/=sd1.cx;
if(nRop & R2_TOP)
r2.bottom=r2.top+sd2.cy;
else if(nRop & R2_BOTTOM)
r2.top=r2.bottom-sd2.cy;
else
{
r2.top=(r2.top+r2.bottom-sd2.cy)>>1;
r2.bottom=r2.top+sd2.cy;
}
}
}
}
if(!(nRop & (R2_STRETCH|R2_ZOOM)))
{
if(nRop & R2_LEFT)
r1.right=r2.left;
else if(nRop & R2_RIGHT)
r1.right=r2.right-sd1.cx;
else
r1.right=(r2.left+r2.right-sd1.cx)>>1;
if(nRop & R2_TOP)
r1.bottom=r2.top;
else if(nRop & R2_BOTTOM)
r1.bottom=r2.bottom-sd1.cy;
else
r1.bottom=(r2.top+r2.bottom-sd1.cy)>>1;
r2.SetRect(r1.BottomRight(),sd1);
r2.IntersectRect(pDestRect);
sd2=r2.TopLeft()-r1.BottomRight();
r1.TopLeft()+=sd2;
sd1=r2.Size();
}
r1.right=r2.left;
r1.bottom=r2.top;
sd2=r2.Size();
r2.IntersectRect(m_rclClip);
if(r2.IsRectEmpty())return;
//初始化光栅操作对象
pDestRect=(LPCRECT)pBitmap->GetPalette();
if(pDestRect)
pDestRect=(LPCRECT)SelectObject((CPalette*)pDestRect);
else
pDestRect=LPCRECT(-1);
rpBmp.SelectObject(pBitmap);
rpBmp.SetRopGetColor(this,pBitmap);
switch(nRop&R2_IFMODEMASK)
{
case R2_RPIFSCREEN:
case R2_RPIFNOTSCREEN:
rp.SetROP(R2_SETPENCOLOR);
rp.c=m_nBkColor;
rp.ROP(rp);
rp.i=rp.c;
rp.SetROP((nRop>>8)&0xff);
pBitmap=(CBitmap*)rp.ROP;
break;
case 0:
if(nRop&R2_ICONLIKE)
nRop|=R2_RPIFNOTPEN;
else
{
pBitmap=NULL;
break;
}
case R2_RPIFPEN:
case R2_RPIFNOTPEN:
if(nRop&R2_ICONLIKE)
rpBmp.MoveTo(0,0);
else
rpBmp.p=DWORD(&m_nBkColor);
rpBmp.ROP(rpBmp);
rp.i=rp.c;
rp.SetROP(R2_IFMODE2MODE(nRop));
pBitmap=(CBitmap*)rp.ROP;
break;
default:
pBitmap=NULL;
}
if(nRop&R2_ALPHAMASK)
rp.SetRopAlpahBlend(nRop>>R2_ALPHASHIFT);
else if((nRop&R2_MODEMASK)==R2_ALPHABLENDPEN)
{
rp.SetROP(R2_SETPENCOLOR);
rp.c=m_nTextColor;
rp.ROP(rp);
rp.SetROP(nRop&R2_MODEMASK);
}
else
rp.SetROP(nRop&R2_MODEMASK);
if(!pBitmap)
pBitmap=(CBitmap*)rp.ROP;
nRop=DWORD(pDestRect);
pDestRect=(LPCRECT)rp.MoveTo(r2.left-m_ptOrg.x,r2.top-m_ptOrg.y);
//绘制图像
if(sd2.cx==sd1.cx && sd2.cy==sd1.cy)
{
r1.left+=r2.left-r1.right;
r1.top+=r2.top-r1.bottom;
pSrcRect=(LPCRECT)rpBmp.MoveTo(r1.left,r1.top);
for(r1.left=r2.left;r2.top<r2.bottom;r2.top++)
{
for(r2.left=r1.left;r2.left<r2.right;r2.left++)
{
rpBmp.ROP(rpBmp);
(PFNROP(pBitmap))(rp);
rp.StepCol();
rpBmp.StepCol();
}
pDestRect=(LPCRECT)rp.StepRow(DWORD(pDestRect));
pSrcRect=(LPCRECT)rpBmp.StepRow(DWORD(pSrcRect));
}
}
else
{
r1.right=r2.left-r1.right;
r1.right*=sd1.cx;
r1.left+=r1.right/sd2.cx;
r1.bottom=r2.top-r1.bottom;
r1.bottom*=sd1.cy;
r1.top+=r1.bottom/sd2.cy;
pSrcRect=(LPCRECT)rpBmp.MoveTo(r1.left,r1.top);
r1.top=r1.right%sd2.cx;
r1.top-=sd2.cx;
r1.bottom%=sd2.cy;
r1.bottom-=sd2.cy;
for(r1.left=r2.left;r2.top<r2.bottom;r2.top++)
{
for(r1.right=r1.top,r2.left=r1.left;r2.left<r2.right;r2.left++)
{
rpBmp.ROP(rpBmp);
(PFNROP(pBitmap))(rp);
rp.StepCol();
r1.right+=sd1.cx;
while(r1.right>=0)
{
rpBmp.StepCol();
r1.right-=sd2.cx;
}
}
pDestRect=(LPCRECT)rp.StepRow(DWORD(pDestRect));
r1.bottom+=sd1.cy;
if(r1.bottom<0)
rpBmp.MoveTo(DWORD(pSrcRect));
else
{
do
{
pSrcRect=(LPCRECT)rpBmp.StepRow(DWORD(pSrcRect));
r1.bottom-=sd2.cy;
}while(r1.bottom>=0);
}
}
}
if(nRop!=-1)SelectObject((CPalette*)nRop);
}
CSize CDC::GetTextExtent(LPCTSTR pszString,int nCount)
{
CSize size;
size.cy=m_pFont->m_nSize;
size.cx=PrvTextWidth(pszString,pszString+nCount,size.cy);
return size;
}
int CDC::DrawText(CWnd* pWnd,LPCRECT pRect,UINT nFormat)
{
return DrawText(pWnd->GetWindowText(),
pWnd->GetWindowTextLength(),pRect,nFormat);
}
int CDC::DrawText(LPCTSTR pszString,int nCount,LPCRECT pRect,UINT nFormat)
{
CRect rect(pRect);
LPCTSTR pszStrEnd=pszString+nCount;
if(nCount<=0)return 0;
if(nFormat&DT_MULTILINE)
{
CCharSet& cs=*m_pFont->m_pCharSet;
CFontFace& ff=*m_pFont->m_pFontFace;
int nHeight=0,nWidth=rect.Width();
DCDTROW dr;
SIZE size;
CPlex *pBlock;
PDCDTROW pRow,pRowEnd;
BYTE block0[sizeof(CPlex)+sizeof(DCDTROW)*DrawTextGrowRow];
pBlock=(CPlex*)block0;
pBlock->m_pNext=NULL;
pRow=(PDCDTROW)pBlock->data();
pRowEnd=pRow+DrawTextGrowRow;
dr.size.cy=m_pFont->m_nSize;
dr.pStr=pszString;
for(;;)
{
pRow->pStr=dr.pStr;
if(pRow->pStr>=pszStrEnd)
break;
dr.pEnd=pszStrEnd;
PrvCalcText(dr,nWidth,nFormat);
pRow->pEnd=dr.pEnd;
pRow->size=dr.size;
if((nFormat&DT_CENTER)==DT_LEFT && *pRow->pEnd=='\t')
{
nWidth-=pRow->size.cx;
size.cx=rect.Width()-nWidth;
size.cy=ff.GetCharWidth('\t',m_pFont->m_nSize);
size.cy*=4-(size.cx/size.cy&3);
nWidth-=size.cy;
}
else
{
nHeight+=dr.size.cy;
nWidth=rect.Width();
}
if(++pRow>=pRowEnd)
{
pRow=(PDCDTROW)CPlex::CreateTail(pBlock,
sizeof(DCDTROW)*DrawTextGrowRow);
pRowEnd=pRow+DrawTextGrowRow;
}
}
if(!(nFormat&DT_CALCRECT) && m_nTextColor==CLR_NONE)
nCount=nHeight;
else{//pBlock=((CPlex*)block0)->m_pNext...
if((nFormat&DT_VCENTER)==DT_BOTTOM)
rect.top=rect.bottom-nHeight;
else if((nFormat&DT_VCENTER)!=DT_TOP)
rect.top=(rect.top+rect.bottom-nHeight)>>1;
if((nFormat&DT_CALCRECT)==DT_CALCRECT)
((CRect*)pRect)->SetRect(MAXLONG,rect.top,MINLONG,rect.top);
if(nFormat&DT_GETCARETPOS)
{
nCount=int(m_nTextColor);
dr.size.cx=nCount;
}
else if(nFormat|DT_GETCARETINDEX)
{
nCount=0;
dr.size.cx=LOWORD(m_nTextColor);
dr.size.cy=HIWORD(m_nTextColor);
}
else
nCount=nHeight;
nHeight=rect.right;
nWidth=rect.left;
pBlock=(CPlex*)block0;
pRow=(PDCDTROW)pBlock->data();
pRowEnd=pRow+DrawTextGrowRow;
for(;;)
{
if(pRow->pStr>=pszStrEnd)
break;
if((nFormat&DT_CENTER)==DT_RIGHT)
{
rect.right=nHeight;
rect.left=nHeight-pRow->size.cx;
}
else
{
if((nFormat&DT_CENTER)!=DT_LEFT)
rect.left=(nWidth+nHeight-pRow->size.cx)>>1;
else if(rect.left<rect.right)
rect.left=nWidth;
rect.right=rect.left+pRow->size.cx;
}
rect.bottom=rect.top+pRow->size.cy;
if((nFormat&DT_CALCRECT)==DT_CALCRECT)
{
CRect& r=*(CRect*)pRect;
if(r.left>rect.left)
r.left=rect.left;
if(r.right<rect.right)
r.right=rect.right;
r.bottom=rect.bottom;
}
else if(nFormat & DT_GETCARETPOS)
{
LPCTSTR pszFind=pszString+dr.size.cx;
if(pRow->pStr>pszFind)
break;
if(pRow->pEnd>pszFind)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -