在背景上输出和擦除文字

在背景上输出文字,并且可以不留痕迹的擦除。
微软提供的 CDC 函数, TextOut 和 DrawText 不支持界面像素的异或运算操作,所以无法从背景中擦除输出的文字。要达到这种目的,只好使用支持像素的异或运算的图形函数了。
有两种方式可以选择:
1.    输出轮廓路径,然后指定画刷填充封闭的路径区域。
2.    得到文字的点阵图,使用向屏幕花点的方式输出文字。
 
下面给出第二种方式的实现代码。
调用两次下面的函数可以擦除输出的文字, 还可以显示按任意角度旋转的文字。
注意:传入的设备上下文变量 pDC ,其中的 ROP2 属性应该指定为 R2_XORPEN 或 R2_NOTXORPEN 

void CDicfexView :: DrawVectorText ( CDC * pDC , CString & strText , CPoint pntPosition , int nAngle )
{if ( strText . IsEmpty ())return ;CClientDC dc ( this );// 确认要按文本输出的坐标映射模式if ( pDC -> GetMapMode () != MM_TEXT ){// 转换到原坐标映射dc . SetROP2 ( pDC -> GetROP2 () );pDC -> LPtoDP ( & pntPosition );pDC = & dc ;}DWORD dwSize ;MAT2 stM2 ;GLYPHMETRICS stGM ;        TEXTMETRIC stTM ;// 创建字体CFont font ;LOGFONT stFont ;memset (& stFont ,0, sizeof ( stFont ));// 设置字体结构的属性;stFont . lfHeight =12;stFont . lfWeight = FW_NORMAL ;stFont . lfClipPrecision = CLIP_LH_ANGLES ;strcpy (( char *) stFont . lfFaceName , "Courier New" );stFont . lfEscapement =  nAngle * 10;stFont . lfOrientation =  nAngle * 10;font . CreateFontIndirect ( & stFont );CFont * pOldFont = pDC -> SelectObject (& font );pDC -> SelectObject (& font );pDC -> GetTextMetrics (& stTM );// 坐标变换矩阵 , 但这种转换时 , 由于精度舍入的原因 , 取得的字体点阵的质量很差 ,// 给 stFont.lfEscapement 变量赋值 , 似乎微软做过优化 , 取得字体点阵勉强能说的过去 ,/*double nEscapement = nAngle * 3.1415926 / 180.0;stM2.eM11 = FloatToFixed(cos(nEscapement));stM2.eM12 = FloatToFixed(sin(nEscapement));stM2.eM21 = FloatToFixed(-sin(nEscapement));stM2.eM22 = FloatToFixed(cos(nEscapement));*/stM2 . eM11 = FloatToFixed (1.0);stM2 . eM12 = FloatToFixed (0.0);stM2 . eM21 = FloatToFixed (0.0);stM2 . eM22 = FloatToFixed (1.0);int nChar = 0; int nSx = pntPosition . x ;int nSy = pntPosition . y ;int nFontSpace = 0;int nCx = 0;int nCy = 0;for ( int i = 0; i < strText . GetLength (); i ++){if ( strText . GetAt ( i ) >= 0)nChar = strText . GetAt ( i );else{// 宽字节int th = strText . GetAt ( i );int tl = strText . GetAt ( i + 1);nChar = (( th & 0x00ff)<<8) + ( tl & 0x00ff);i ++;}// 得到字体轮廓信息的尺寸dwSize = pDC -> GetGlyphOutline ( nChar , GGO_BITMAP ,& stGM , 0L , NULL ,& stM2 );// 定义缓冲区BYTE * pBuffer = new BYTE [ dwSize ];memset ( pBuffer , 0, dwSize );// 取得字体轮廓pDC -> GetGlyphOutline ( nChar , GGO_BITMAP , & stGM , dwSize , pBuffer , & stM2 );int nStride = dwSize / stGM . gmBlackBoxY ;// 轮廓数据OUTLINETEXTMETRIC    stOtm ; memset ( & stOtm , 0, sizeof ( stOtm ) ); stOtm . otmSize = sizeof ( stOtm ); pDC -> GetOutlineTextMetrics ( sizeof ( stOtm ), & stOtm );//x 的偏移量int nXOffset = stGM . gmptGlyphOrigin . x ;    //y 的偏移量    字的顶部        - y 方向原点  都是相对于 baseline int nYOffset = stOtm . otmAscent - stGM . gmptGlyphOrigin . y ;   for ( int y =0; y < stGM . gmBlackBoxY ; ++ y ){for ( int x =0; x < nStride ; ++ x ){for ( int k =0; k < 8; ++ k ){if ( ( pBuffer [ y * nStride + x ] >> (7- k ) ) & 1 ){int nX = nCx + 8 * x + k + nXOffset ;int nY = nCy + y + nYOffset ;pDC -> SetPixel ( nSx + nX , nSy + nY , RGB (255,200,200) );}}}}// 设置下一个字符的位置nCx += stGM . gmCellIncX ;nCx += nFontSpace ;nCy += stGM . gmCellIncY ;delete [] pBuffer ;}pDC -> SelectObject ( pOldFont );
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部