www.pudn.com > WinGOS.rar > 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.topm_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.top0;) 
	{ 
		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(nMaxY0;) 
			{ 
				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(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.topm_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.cyr2.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>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=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.leftsize.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.rightpStr>pszFind) 
					break; 
				if(pRow->pEnd>pszFind) 
				{ 
					size.cx=rect.left; 
					dr.pEnd=pRow->pStr; 
					while(dr.pEndpEnd) 
					{ 
						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.pEndpEnd) 
					{ 
						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)>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)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.bottom) 
		return; 
	if(x1=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.right) 
		return; 
	if(y1=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(x1y2)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>1; 
		for(;y1=dy) 
			{ 
				x2-=dy; 
				rp.Offset(sx); 
			} 
		} 
	} 
	else 
	{ 
		y2=dx>>1; 
		for(;x1=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(ypt1.x) 
			*pMinX=pt1.x; 
		if(*pMaxX>1))/pt1.y; 
		pt2.x+=pt1.y; 
	} 
	if(*pMinX>pt2.x) 
		*pMinX=pt2.x; 
	if(*pMaxXm_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=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.hm_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(pszStringm_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.pStr0) 
#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; 
		} 
	} 
}