📄 dc.cpp
字号:
{
size.cx=rect.left;
dr.pEnd=pRow->pStr;
while(dr.pEnd<pRow->pEnd)
{
if(dr.pEnd>=pszFind)
{
nCount=(rect.top+rect.bottom)>>1;
m_nTextColor=MAKELONG(size.cx,nCount);
nCount=dr.pEnd-pszString;
break;
}
size.cy=cs.ParseText(dr.pEnd);
size.cx+=ff.GetCharWidth(size.cy,m_pFont->m_nSize);
}
break;
}
nCount=(rect.top+rect.bottom)>>1;
m_nTextColor=MAKELONG(rect.right,nCount);
nCount=pRow->pEnd-pszString;
}
else if(nFormat & DT_GETCARETINDEX)
{
if(rect.top>dr.size.cy)
break;
if(rect.bottom>dr.size.cy)
{
size.cx=rect.left;
dr.pEnd=pRow->pStr;
while(dr.pEnd<pRow->pEnd)
{
dr.pStr=dr.pEnd;
nCount=cs.ParseText(dr.pEnd);
size.cy=ff.GetCharWidth(nCount,m_pFont->m_nSize);
size.cx+=size.cy;
if(size.cx>dr.size.cx)
{
nCount=(rect.top+rect.bottom)>>1;
if(size.cx-(size.cy>>1)<dr.size.cx)
{
m_nTextColor=MAKELONG(size.cx,nCount);
nCount=dr.pEnd-pszString;
}
else
{
m_nTextColor=MAKELONG(size.cx-size.cy,nCount);
nCount=dr.pStr-pszString;
}
dr.pEnd=NULL;
break;
}
}
if(!dr.pEnd)
break;
}
nCount=(rect.top+rect.bottom)>>1;
m_nTextColor=MAKELONG(rect.right,nCount);
nCount=pRow->pEnd-pszString;
}
else
{
CRect r(rect);
PrvDrawText(r,pRow->pStr,pRow->pEnd,nFormat);
}
if((nFormat&DT_CENTER)==DT_LEFT && *pRow->pEnd=='\t')
{
size.cy=ff.GetCharWidth('\t',m_pFont->m_nSize);
size.cy*=4-((rect.right-pRect->left)/size.cy&3);
rect.left=rect.right+size.cy;
if((nFormat & DT_GETCARETINDEX) &&
(nFormat&DT_CALCRECT)!=DT_CALCRECT &&
rect.bottom>dr.size.cy && rect.left>dr.size.cx)
{
nCount=(rect.top+rect.bottom)>>1;
if(rect.left-(size.cy>>1)<dr.size.cx)
{
m_nTextColor=MAKELONG(rect.left,nCount);
nCount=pRow->pEnd-pszString+1;
}
else
{
m_nTextColor=MAKELONG(rect.left-size.cy,nCount);
nCount=pRow->pEnd-pszString;
}
break;
}
}
else
rect.top=rect.bottom;
if(++pRow>=pRowEnd)
{
pBlock=pBlock->m_pNext;
pRow=(PDCDTROW)pBlock->data();
pRowEnd=pRow+DrawTextGrowRow;
}
}}//...m_nTextColor==CLR_NONE)
pBlock=((CPlex*)block0)->m_pNext;
pBlock->FreeDataChain();
}
else if(nFormat&DT_FILLFULLRECT)
{
nCount=rect.Height();
PrvFillText(rect,pszString,pszStrEnd);
}
else
{
SIZE size;
size.cy=m_pFont->m_nSize;
size.cx=PrvTextWidth(pszString,pszStrEnd,size.cy);
if((nFormat&DT_CENTER)==DT_RIGHT)
rect.left=rect.right-size.cx;
else
{
if((nFormat&DT_CENTER)!=DT_LEFT)
rect.left=(rect.left+rect.right-size.cx)>>1;
rect.right=rect.left+size.cx;
}
if((nFormat&DT_VCENTER)==DT_BOTTOM)
rect.top=rect.bottom-size.cy;
else
{
if((nFormat&DT_VCENTER)!=DT_TOP)
rect.top=(rect.top+rect.bottom-size.cy)>>1;
rect.bottom=rect.top+size.cy;
}
nCount=rect.Height();
if((nFormat&DT_CALCRECT)==DT_CALCRECT)
*(CRect*)pRect=rect;
else if(m_nTextColor!=CLR_NONE)
PrvDrawText(rect,pszString,pszStrEnd,nFormat);
}
return nCount;
}
void CDC::PrvFillEllipse(LPCRECT pRect)
{
int x0,y0,x,y,a2,b2,a,b,xb2,ya2,sum,s;
CRect r;
x=pRect->left;
y=pRect->top;
a2=pRect->right-1;
b2=pRect->bottom-1;
a=(a2-x)>>1;
b=(b2-y)>>1;
x0=(x+a2)>>1;
y0=(y+b2)>>1;
a2=a*a;
b2=b*b;
if(a<=0 || b<=0)
return;
x=0;
y=b;
sum=0;
for(;;)
{
xb2=b2*x<<1;
ya2=a2*y<<1;
s=ya2-a2;
if(sum>(s>>1))
{
r.SetRect(x0-x,y0-y,x0+x+1,y0-y+1);
FillRect(&r);
r.SetRect(x0-x,y0+y,x0+x+1,y0+y+1);
FillRect(&r);
y--;
sum-=s;
if(!y)break;
}
else
{
x++;
sum+=xb2+b2;
}
}
r.SetRect(x0-a,y0,x0+a,y0+1);
FillRect(&r);
}
void CDC::PrvLine(POINT pt1,POINT pt2)
{
if(pt1.y==pt2.y)
{
if(pt1.x<=pt2.x)
PrvLineH(pt1.y,pt1.x,pt2.x);
else
PrvLineH(pt1.y,pt2.x,pt1.x);
}
else if(pt1.x==pt2.x)
{
if(pt1.y<=pt2.y)
PrvLineV(pt1.x,pt1.y,pt2.y);
else
PrvLineV(pt1.x,pt2.y,pt1.y);
}
else
PrvLineI(pt1,pt2);
}
void CDC::PrvLineH(int y,int x1,int x2)
{
CROP &rp=m_rop;
CRect& rc=m_rclClip;
int nPS=m_pPen->m_nStyle;
if(nPS==PS_NULL)
return;
if(y<m_rclClip.top || y>=m_rclClip.bottom)
return;
if(x1<m_rclClip.left)
x1=m_rclClip.left;
if(x2>=m_rclClip.right)
x2=m_rclClip.right-1;
rp.MoveTo(x1-m_ptOrg.x,y-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,m_pPen->m_crColor);
for(;x1<=x2;x1++)
{
y=1<<(x1&31);
if(nPS & y)
rp.ROP(rp);
rp.StepCol();
}
}
void CDC::PrvLineV(int x,int y1,int y2)
{
CROP &rp=m_rop;
CRect& rc=m_rclClip;
int nPS=m_pPen->m_nStyle;
if(nPS==PS_NULL)
return;
if(x<m_rclClip.left || x>=m_rclClip.right)
return;
if(y1<m_rclClip.top)
y1=m_rclClip.top;
if(y2>=m_rclClip.bottom)
y2=m_rclClip.bottom-1;
rp.MoveTo(x-m_ptOrg.x,y1-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,m_pPen->m_crColor);
for(;y1<=y2;y1++)
{
x=1<<(y1&31);
if(nPS & x)
rp.ROP(rp);
rp.StepRow();
}
}
void CDC::PrvLineI(POINT pt1,POINT pt2)
{
CROP &rp=m_rop;
CRect& rc=m_rclClip;
int nPS=m_pPen->m_nStyle;
int dx,dy,x1,y1,x2,y2,sx,sy;
if(nPS==PS_NULL)
return;
//映射到第一象限
sx=pt2.x-pt1.x;
sy=pt2.y-pt1.y;
if(sx>=0)
{
dx=sx;
x1=rc.left;
x2=rc.right-1;
}
else
{
dx=-sx;
pt1.x=-pt1.x;
pt2.x=-pt2.x;
x1=1-rc.right;
x2=-rc.left;
}
if(sy>=0)
{
dy=sy;
y1=rc.top;
y2=rc.bottom-1;
}
else
{
dy=-sy;
pt1.y=-pt1.y;
pt2.y=-pt2.y;
y1=1-rc.bottom;
y2=-rc.top;
}
//剪切线段
x1=(x1-pt1.x)*dy;
x2=(x2-pt1.x)*dy;
y1=(y1-pt1.y)*dx;
y2=(y2-pt1.y)*dx;
if(x1<y1)x1=y1;
if(x1<0)x1=0;
if(x2>y2)x2=y2;
y2=dx*dy;
if(x2>y2)x2=y2;
y1=pt1.y+(x1+(dx>>1))/dx;
x1=pt1.x+(x1+(dy>>1))/dy;
y2=pt1.y+(x2+(dx>>1))/dx;
x2=pt1.x+(x2+(dy>>1))/dy;
//初始化Pixel
rp.MoveTo((sx<0?-x1:x1)-m_ptOrg.x,(sy<0?-y1:y1)-m_ptOrg.y);
rp.SetRopByPenColor(m_nDrawMode,m_pPen->m_crColor);
sx=sx<0?-rp.GetColStep():rp.GetColStep();
sy=sy<0?-rp.GetRowStep():rp.GetRowStep();
//绘制
if(dx<dy)
{
x2=dy>>1;
for(;y1<y2;y1++)
{
x1=1<<(y1&31);
if(nPS & x1)
rp.ROP(rp);
rp.Offset(sy);
x2+=dx;
if(x2>=dy)
{
x2-=dy;
rp.Offset(sx);
}
}
}
else
{
y2=dx>>1;
for(;x1<x2;x1++)
{
y1=1<<(x1&31);
if(nPS & y1)
rp.ROP(rp);
rp.Offset(sx);
y2+=dy;
if(y2>=dx)
{
y2-=dx;
rp.Offset(sy);
}
}
}
}
void CDC::PrvPolygon(POINT pt1,POINT pt2,int y,int* pMinX,int* pMaxX)
{
if(y>pt1.y && y>pt2.y)
return;
if(y<pt1.y && y<pt2.y)
return;
if(pt1.y==pt2.y)
{
if(*pMinX>pt1.x)
*pMinX=pt1.x;
if(*pMaxX<pt1.x)
*pMaxX=pt1.x;
}
else if(pt1.x!=pt2.x)
{
//(x-x0)=(x1-x0)*(y-y0)/(y1-y0);
pt1.x-=pt2.x;
pt1.x*=y-pt2.y;
pt1.y-=pt2.y;
pt1.y=(pt1.x+(pt1.y>>1))/pt1.y;
pt2.x+=pt1.y;
}
if(*pMinX>pt2.x)
*pMinX=pt2.x;
if(*pMaxX<pt2.x)
*pMaxX=pt2.x;
}
void CDC::PrvFillText(CRect& rect,LPCTSTR pszString,LPCTSTR pszStrEnd)
{
CCharSet& cs=*m_pFont->m_pCharSet;
CFontFace& ff=*m_pFont->m_pFontFace;
int nSize,nSize0=ff.GetFontFace().nHeight;
POINT ptPos=rect.TopLeft();
int nBaseLine=rect.bottom;
FFDRAWARG pv;
int dx,fdx;
dx=rect.right-rect.left;
pv.sd.cy=rect.bottom-rect.top;
rect.IntersectRect(m_rclClip);
if(rect.IsRectEmpty())return;
fdx=PrvTextWidth(pszString,pszStrEnd,nSize0);
nSize=dx>>1;
pv.rp=m_rop;
pv.rp.SetRopByPenColor(R2_COPYPEN,m_nTextColor);
if(m_nBkColor==CLR_NONE)
pv.pBkRop=NULL;
else
{
m_rop.SetRopByPenColor(R2_COPYPEN,m_nBkColor);
pv.pBkRop=&m_rop;
}
while(pszString<pszStrEnd)
{
pv.nCharCode=cs.ParseText(pszString);
pv.sfd.cx=ff.GetCharWidth(pv.nCharCode,nSize0);
pv.sfd.cy=nSize0;
pv.sd.cx=pv.sfd.cx*dx;
nSize+=pv.sd.cx%fdx;
if(nSize>=0){nSize-=fdx;pv.sd.cx++;}
pv.sd.cx/=fdx;
rect.SetRect(ptPos,pv.sd);
rect.IntersectRect(m_rclClip);
pv.pData=ff.FindChar(pv.nCharCode);
if(!pv.pData || rect.IsRectEmpty())
{
ptPos.x+=pv.sd.cx;
continue;
}
pv.nPos=pv.rp.MoveTo(rect.left-m_ptOrg.x,rect.top-m_ptOrg.y);
pv.w=rect.Width();
pv.h=rect.Height();
pv.nDxSum=rect.left-ptPos.x;
pv.nDxSum*=pv.sfd.cx;
pv.nDySum=rect.top-ptPos.y;
pv.nDySum*=pv.sfd.cy;
pv.x=pv.nDxSum/pv.sd.cx;
pv.y=pv.nDySum/pv.sd.cy;
pv.nDxSum%=pv.sd.cx;
pv.nDxSum-=pv.sd.cx;
pv.nDySum%=pv.sd.cy;
pv.nDySum-=pv.sd.cy;
ptPos.x+=pv.sd.cx;
ff.DrawFont(pv);
}
}
void CDC::PrvDrawText(CRect& rect,LPCTSTR pszString,LPCTSTR pszStrEnd,UINT nFormat)
{
CCharSet& cs=*m_pFont->m_pCharSet;
CFontFace& ff=*m_pFont->m_pFontFace;
int nSize=m_pFont->m_nSize,nSize0=ff.GetFontFace().nHeight;
POINT ptPos=rect.TopLeft();
FFDRAWARG pv;
rect.IntersectRect(m_rclClip);
if(rect.IsRectEmpty())
return;
pv.rp=m_rop;
pv.rp.SetRopByPenColor(R2_COPYPEN,m_nTextColor);
if(m_nBkColor==CLR_NONE)
pv.pBkRop=NULL;
else
{
m_rop.SetRopByPenColor(R2_COPYPEN,m_nBkColor);
pv.pBkRop=&m_rop;
}
if(nFormat & (DT_UNDERLINE|DT_STRIKELINE))
{
pv.h=ptPos.y;
pv.h+=(nFormat&DT_UNDERLINE)?nSize-1:(nSize>>1);
pv.w=rect.left;
pv.rp.MoveTo(pv.w-m_ptOrg.x,pv.h-m_ptOrg.y);
if(pv.h>=rect.top && pv.h<rect.bottom)
{
for(;pv.w<rect.right;pv.w++)
{
pv.rp.ROP(pv.rp);
pv.rp.StepCol();
}
}
}
while(pszString<pszStrEnd)
{
pv.nCharCode=cs.ParseText(pszString);
pv.sd.cx=ff.GetCharWidth(pv.nCharCode,nSize);
pv.sd.cy=nSize;
if(nSize==nSize0)
pv.sfd=pv.sd;
else
{
pv.sfd.cx=ff.GetCharWidth(pv.nCharCode,nSize0);
pv.sfd.cy=nSize0;
}
rect.SetRect(ptPos,pv.sd);
rect.IntersectRect(m_rclClip);
pv.pData=ff.FindChar(pv.nCharCode);
if(!pv.pData || rect.IsRectEmpty())
{
ptPos.x+=pv.sd.cx;
continue;
}
pv.nPos=pv.rp.MoveTo(rect.left-m_ptOrg.x,rect.top-m_ptOrg.y);
pv.w=rect.Width();
pv.h=rect.Height();
if(nSize!=nSize0)
{
pv.nDxSum=rect.left-ptPos.x;
pv.nDxSum*=pv.sfd.cx;
pv.nDySum=rect.top-ptPos.y;
pv.nDySum*=pv.sfd.cy;
pv.x=pv.nDxSum/pv.sd.cx;
pv.y=pv.nDySum/pv.sd.cy;
pv.nDxSum%=pv.sd.cx;
pv.nDxSum-=pv.sd.cx;
pv.nDySum%=pv.sd.cy;
pv.nDySum-=pv.sd.cy;
}
else
{
pv.nDxSum=0;
pv.nDySum=0;
pv.x=rect.left-ptPos.x;
pv.y=rect.top-ptPos.y;
}
ptPos.x+=pv.sd.cx;
ff.DrawFont(pv);
}
}
int CDC::PrvTextWidth(LPCTSTR pszString,LPCTSTR pszStrEnd,int nFontSize)
{
CFontFace& ff=*m_pFont->m_pFontFace;
int nWidth;
if(ff.GetFontFace().nType&FONTTYPE_MONOSPACED)
{
nWidth=ff.GetCharWidth(' ',nFontSize);
nWidth*=pszStrEnd-pszString;
}
else
{
DWORD nCharCode;
CCharSet& cs=*m_pFont->m_pCharSet;
nWidth=0;
while(pszString<pszStrEnd)
{
nCharCode=cs.ParseText(pszString);
nWidth+=ff.GetCharWidth(nCharCode,nFontSize);
}
}
return nWidth;
}
void CDC::PrvCalcText(DCDTROW& dr,int nWidth,UINT nFormat)
{
CCharSet& cs=*m_pFont->m_pCharSet;
CFontFace& ff=*m_pFont->m_pFontFace;
LPCTSTR pStr,pszWB=NULL;
int nFlags,nSize=m_pFont->m_nSize;
DWORD nCharCode;
int nCharWidth,nWbWidth;
if(ff.GetFontFace().nType&FONTTYPE_MONOSPACED)
nSize=ff.GetCharWidth(' ',nSize);
else
nSize=-nSize;
dr.size.cx=0;
while(dr.pStr<dr.pEnd)
{
pStr=dr.pStr;
nCharCode=cs.ParseText(dr.pStr);
if(nSize>0)
#ifdef _UNICODE
nCharWidth=nSize;
#else
nCharWidth=nCharCode>255?nSize<<1:nSize;
#endif
else
nCharWidth=ff.GetCharWidth(nCharCode,-nSize);
switch(nCharCode)
{
case '\r':
if(*dr.pStr=='\n')
dr.pStr++;
case '\n':
nFlags=2;
break;
case '\t':
if((nFormat&DT_CENTER)==DT_LEFT)
{
nFlags=2;
break;
}
default:
nFlags=(nFormat&DT_WORDBREAK)&&(dr.size.cx+nCharWidth>nWidth)?1:0;
}
if(nFlags)
{
if(nFlags==2)
{
dr.pEnd=pStr;
}
else if(pszWB)
{
dr.pEnd=pszWB;
dr.size.cx=nWbWidth;
dr.pStr=pszWB;
}
else
{
dr.pEnd=pStr;
dr.pStr=pStr;
}
break;
}
dr.size.cx+=nCharWidth;
if(cs.GetCharType(nCharCode)&CHARTYPE_WORDBREAK)
{
nWbWidth=dr.size.cx;
pszWB=dr.pStr;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -