前言
前面已经介绍了图形绘制,本篇将介绍简单的文字输出操作方法。其实文字在计算机中也是作为图形处理的,只是一种特殊的图形,是按固定预设字模图形来绘制的,称为字体。文字输出就是按文字所在字体中的对应图形绘制出来,因此同一个文字可以有不同字体输出,显示出来的文字图形就不一样。
一、文字输出方法
SimpleCG支持以下输出函数:
//在规定的位置绘制文本。其中x和y为坐标
void outtextXY(int x, int y, const CHAR *pText);
//在规定的矩形框内绘制文本
void outtextRect(int nLeft, int nTop, int nWidth, int nHeight, const CHAR *pText);
//在规定的矩形框内按格式绘制文本
void outtextRectEx(int nLeft, int nTop, int nWidth, int nHeight, const CHAR *pText, UINT nFormat );
//格式化输出文本
//在规定的位置绘制格式化文本。其中x和y为坐标
void printfXY(int x, int y, const CHAR *pFormat, ...);
//在规定的矩形框内绘制格式化文本
void printfRect(int nLeft, int nTop, int nWidth, int nHeight, const CHAR *pFormat, ... );
//在规定的矩形框内绘制格式化文本
void printfRectEx(int nLeft, int nTop, int nWidth, int nHeight, UINT nFormat, const CHAR *pFormat, ... );
最简单的绘制方式就是直接在指定位置绘制文字,使用outtextXY函数,位置参数指定文字左上角的坐标。
例如
outtextXY( 0,0, _T("测试文字输出"));
在窗口左上角用默认字体,默认大小绘制“测试文字输出”几个字。
outtextXY很简单,但只能输出到指定位置,无法限制在指定区域内,如果要自动裁切区域,就要使用另外一个函数--outtextRect。下面看看一个绘制按钮的例子
setbackmode(enumBKM_TRANSPARENT);
setfillcolor(RGB(0xAA,0xAA,0xFF));
int nY=0;
fillroundrect( 50,50+nY*50,150,60+nY*50, 5,5);
outtextRectEx(50,50+nY*50,100,10,_T("新建测试"),SCG_TEXT_MIDDLE);
nY++;
fillroundrect( 50,50+nY*50,150,80+nY*50, 5,5);
outtextRectEx(50,50+nY*50,100,30,_T("打开测试"),SCG_TEXT_MIDDLE);
nY++;
fillroundrect( 50,50+nY*50,150,80+nY*50, 5,5);
outtextRectEx(50,50+nY*50,100,30,_T("保存测试"),SCG_TEXT_MIDDLE);
对于有区域限制的文本绘制,非常有用
效果如图
可以看到第一个按钮由于按钮高度设置不够,文字无法完全显示在按钮上,出现了自动裁剪,不至于文字绘制出格。
此外对于C语言初学者,可能习惯于使用printf函数输出文字,那么可以选择对应的
//格式化输出文本
//在规定的位置绘制格式化文本。其中x和y为坐标
void printfXY(int x, int y, const CHAR *pFormat, ...);
//在规定的矩形框内绘制格式化文本
void printfRect(int nLeft, int nTop, int nWidth, int nHeight, const CHAR *pFormat, ... );
//在规定的矩形框内绘制格式化文本
void printfRectEx(int nLeft, int nTop, int nWidth, int nHeight, UINT nFormat, const CHAR *pFormat, ... );
使用方法与printf差不多,就是需要提供绘制位置。
二、与文字输出相关设置
1、颜色设置
//获取文字颜色
COLORREF gettextcolor();
//设置文字颜色
COLORREF settextcolor(COLORREF color);
这个前面的例子已经介绍了,直接提供颜色参数就可以了。
2、字体设置
//字体设置
void settextfont( LONG nHeight, LONG nWidth, LPCSTR lpszFace );
void settextfontEx( const LOGFONTW* pLogFont );
//设置字体样式enumSFS_NORMAL=正常, enumSFS_ITALIC=倾斜, enumSFS_UNDERLINE=下划线, enumSFS_STRIKEOUT=划线
void settextfontStyle( int nStyle );
//按字号设置大小
void settextfontPointSize( LONG nPoint );
//设置字体粗细
void settextfontWeight( int nWeight );
下面看看不同的字体设置绘制出的文字区别如何
//默认
int nY=0;
int nHeight = 35;
LOGFONT lf = *gettextfont();
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfont( 20, 30, _T("隶书"));
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfont( 20, 10, _T("宋体"));
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontStyle( enumSFS_ITALIC );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontStyle( enumSFS_UNDERLINE );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontStyle( enumSFS_STRIKEOUT );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontStyle( enumSFS_NORMAL );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontEx(&lf);
settextfontPointSize( 12 );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
settextfontPointSize( 24 );
nY++;
outtextXY( 10,10+nY*nHeight,_T("SimpleCG测试效果"));
int i=0;
nY++;
for(i=0;i<1000;i+=100)
{
settextfontWeight( i );
outtextXY( 10+i/2,10+nY*nHeight,_T("测"));
}
效果如图
总结
以上就是文字输出的基本方法,要想进一步掌握windows的文字输出,可以进一步研究windows的字体相关知识,加上一些想象力就可以做出酷炫的文字特效。对于一般的文本输出则只要掌握基本的知识已经够用了。欢迎有兴趣的同学下载simplecg库来进一步学习研究。
最后用一个古时有名的遇仙桥碑刻演示文字输出的用法。
代码如下:
// Text.cpp : 定义控制台应用程序的入口点。
//
#include "../import/include/CGBoard.h"
#include "math.h"
#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endif
#define C_CHAR_HEIGHT 30
enum ENUM_DIRECTION
{
enumDIR_UP,
enumDIR_RIGHT,
enumDIR_DOWN,
enumDIR_LEFT,
};
int g_nWidth = 500; //画面宽度
int g_nHeight= 400; //画面高度
int g_pIsOn[9][9] = {0};
void DrawCharacter( int nX, int nY, WCHAR pText, COLORREF nColor, int nDir )
{
WCHAR pOutput[2]={0};
pOutput[0] = pText;
setfillcolor(nColor);
setbackmode(enumBKM_TRANSPARENT);
solidrectangle(nX * C_CHAR_HEIGHT, nY*C_CHAR_HEIGHT, nX * C_CHAR_HEIGHT+C_CHAR_HEIGHT, nY*C_CHAR_HEIGHT+C_CHAR_HEIGHT);
outtextRectExW( nX * C_CHAR_HEIGHT, nY*C_CHAR_HEIGHT, C_CHAR_HEIGHT, C_CHAR_HEIGHT, pOutput, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
}
void DrawPoem()
{
int nDir = enumDIR_DOWN;
WCHAR pPoemTitle[] = L"题遇仙桥";
WCHAR pPoem[] = L"牛郎织女会佳期下弹琴又赋诗静忽闻钟鼓響停始觉月光移少黄冠归道观机而作尽忘机时得到桃源洞彼仙人下象棋";
WCHAR *pPoemSrc[] = { L"牛郎织女会佳期",L"月下弹琴又赋诗",L"寺静忽闻钟鼓響",L"音停始觉月光移",L"多少黄冠归道观",L"见机而作尽忘机",L"几时得到桃源洞",L"同彼仙人下象棋"};
int nIndex = 0;
int nX = 5;
int nY = 5;
POINT ptDir[] = { {0,-1}, {1,0},{0,1},{-1,0}};
int nCount = 0;
srand(GetTickCount());
COLORREF nColor = RGB(200+rand()%56,200+rand()%56,200+rand()%56);
for(nIndex=0; nIndex<sizeof(pPoem)/sizeof(pPoem[0])-1;++nIndex)
{
DrawCharacter( nX, nY, pPoem[nIndex],nColor,nDir);
g_pIsOn[nY][nX] = 1;
nX += ptDir[nDir].x;
nY += ptDir[nDir].y;
++nCount;
if(nCount>=7)
{
nColor = RGB(200+rand()%56,200+rand()%56,200+rand()%56);
nCount = 1;
}
int nNew=nDir+1;
if( nNew>enumDIR_LEFT )
nNew = enumDIR_UP;
if( g_pIsOn[nY +ptDir[nNew].y][nX + ptDir[nNew].x] == 0 )
nDir = nNew;
}
outtextXYW(200,30,pPoemTitle);
for(nIndex=0; nIndex<sizeof(pPoemSrc)/sizeof(pPoemSrc[0]);++nIndex)
{
nColor = RGB(rand()%200,rand()%200,rand()%200);
settextcolor(nColor);
outtextXYW(300,60+nIndex*30,pPoemSrc[nIndex]);
}
ReflushWindow();
}
void DrawProcess()
{
DrawPoem();
}
int _tmain(int argc, _TCHAR* argv[])
{
//初始化
if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))
return 1;
//关闭图库
CloseBoard();
return 0;
}
演示如下:
这首碑刻从中间开始读,然后首位相连,思维的巧妙,令人赞叹。