精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。需要全文内容也请联系孙老师。
The function provided here can be used to draw a text string with an oblique or slant angle. Such text outputs are useful in isometric or perspective 3D views to make the text strings look like in their 3D space. An example is shown in the following picture:
这里提供的函数可以用来画一个斜线或者倾斜的文本字符串。这样的文本输出被用于等距或3d视图,让文本字符串看起来像在3d空间。例如下图所示:
Windows GDI function TextOut() does not allow a text slant angle. To draw such slanted strings, we need to set a transformation using SetWorldTransform(). Windows drawing function will then take care of the shearing and rotation of the output. This procedure is incorporated into a new function similar to Windows TextOut() function:
Windows GDI TextOut函数()不允许文本倾斜角。画这样的倾斜的字符串,我们需要设置转换使用SetWorldTransform()。Windows绘图函数将处理剪切和输出的旋转。此过程被加入到类似Windows的TextOut()函数功能的新功能::
void ObliqueTextOut( CDC *dc, int oblique, int x,int y,const CString &Text )
This function has the same arguments as Windows TextOut() function with an additional argument, oblique, to specify the text slant angle. The function can be placed where TextOut() is normally used.
这个函数和Windows TextOut()函数有相同的参数,也使用一个额外的参数,oblique,指定文本倾斜角度。该功能可以放在TextOut()正常使用。
Insert the function source code into your source code file. Call the function at places where you would normally call Windows TextOut() function. Remember to select the font, set the text background mode, color and background color etc, as you would normally do before calling TextOut().
函数源代码插入到您的源代码文件。调用函数,你通常会调用Windows TextOut()函数。记得选择字体,设置文本背景模式,颜色和背景颜色等,因为你通常会在调用TextOut()之前做这些。
Angle oblique is positive if the text slants forward(to the right) and negative if it slants backwards(to the left). The oblique angle, s, in the figure below is positive. The angle is in 1/10th degrees. Therefore, if the text slants forward 15 degrees, oblique=150.
如果文本偏向前(右)角度是正的,如果它向后偏(左)角度是负的。斜角在数字下边是正的。角度是 1/10th 度。因此,如果文本向前偏15度,oblique= 150。
The key to the question is to set up the transformation in DC. Function SetWorldTransform() needs an XFORM structure for the transformation. Therefore, we need to prepare the XFORM structure before calling SetWorldTransform( ). XFORM has 6 member data. They are eM11, eM21, eM12, eM22, eDx, eDx. They are defined as:
问题的关键是建立在DC转换。SetWorldTransform()函数需要一个XFORM结构转换。因此,我们需要在准备变换结构之前调用SetWorldTransform()。变换有6个成员数据。他们是eM11, eM21, eM12, eM22, eDx, eDx。他们被定义为:
X = eM11 * x + eM21 * y + eDxY = eM12 * x + 2M22 * y + eDy
where (x,y) are the World coordinates and (X,Y) are the Paper space coordinates.其中(x,y)是自然空间坐标和(X,Y)是在平面空间坐标。
In the figure below, x,y are the World space axes. The string will always be drawing at (0,0) and horizontally in the world space. xs,ys are the Sheared space axes. The transformation from World to the Sheared space is: 在下面的图中,x,y是自然空间轴。字符串总是在(0,0)和水平在自然空间绘制。XS,YS是裁剪空间轴。从自然裁剪空间到裁剪空间转换:
xs = x - y * tan(s) ys = y
where s is the slant or oblique angle. 其中s是倾斜或斜角。
The Paper space is noted as X,Y. From the Sheared space to Paper space, the transformation is a rotation(angle r) and translation(Xo,Yo). 平面空间记为X,Y。从裁剪空间到平面空间,转换是一个旋转(角度r)和平移(Xo,Yo)的过程。
X = Xo + xs * cos(r) + ys * sin(r) Y = Yo + ys * cos(r) - xs * sin(r)
Where (Xo,Yo) are simply the text insertion point in Paper space. Substitute (xs,ys) into the above, we get:其中(XO,YO)只是在平面空间文本插入点。替补(XS,YS)到上述情况,我们得到:
X = cos(r) * x + (sin(r)-tan(s)*cos(r)) * y + Xo Y = -sin(r) * x + (cos(r)+tan(s)*sin(r)) * y + Yo
Compare this to the XFORM structure, it is obvious that: 与此相比,在XFORM结构,很明显的是:
eM11 = cos(r) eM21 = sin(r) - tan(s) * cos(r) eM12 = -sin(r) eM22 = cos(r) + tan(s) * sin(r) eDx = Xo eDy = Yo
The above is translated into function code(dc is the input device context): 以上被翻译成函数代码(DC是输入设备上下文):
XFORM xForm; xForm.eDx = (float) x;xForm.eDy = (float) y; xForm.eM11 = (float) cos(txtRotate); xForm.eM21 = (float) (sin(txtRotate) - tan(txtOblique)*cos(txtRotate)); xForm.eM12 = (float) -sin(txtRotate); xForm.eM22 = (float) (cos(txtRotate) + tan(txtOblique)*sin(txtRotate)); SetGraphicsMode( dc->m_hDC, GM_ADVANCED ); SetWorldTransform( dc->m_hDC, &xForm );
The call to SetGraphicsMode() is needed. Otherwise, function SetWorldTranform() will have no effect. Since now we are drawing in World space, we need to adjust the font's rotation(lfEscapement) to be horizontal and the character orientation(lfOrintation) to be from the World X-axis.
SetGraphicsMode()的调用是必要的。否则,SetWorldTranform()函数将没有任何效果。因为现在我们在自然空间里绘图,我们需要从自然x轴调整字体的旋转(lfEscapement)水平和取向(lfOrintation)。
LOGFONT lgf; dc->GetCurrentFont()->GetLogFont( &lgf ); ... lgf.lfOrientation -= lgf.lfEscapement; lgf.lfEscapement = 0; CFont horFont; horFont.CreateFontIndirect( &lgf ); CFont *OldFont = dc->SelectObject( &horFont );
Now, we can call: 现在,我们可以调用:
dc->TextOut( 0,0, Text );
The work is done. But before returning, we need to restore the graphics mode and font: 这项工作已经完成。但在返回之前,我们需要恢复图形模式和字体:
ModifyWorldTransform( dc->m_hDC, &xForm, MWT_IDENTITY );
SetGraphicsMode( dc->m_hDC, GM_COMPATIBLE );
dc->SelectObject( OldFont );