TLogFont中使字体为斜体只能有固定的倾斜程度,如何实现任意角度的倾斜?
解决方案 »
- delphi exception eolesyserror in module project1.exe
- 关于 invalid variant type conversion 错误
- XP预览问题
- 为什么缺少方法啊?
- InternetSetOption(hSession, Internet_OPTION_CONNECT_TIMEOUT, @TimeOut, 4);
- 自动拔下Usb功能
- 怎么利用递归根据数据库内容生成TREEVIEW?急急急
- 意外发生时, 跳出一个过程后, 怎样设置它的断点?
- 所有的分求解决:ADOQuery查询出错!!!!,程序如下:
- 500分求助
- DBNavigator的问题?
- ◆★。.^×*@ Delphi全体版主祝朋友们新年快乐,万事如意!
FillChar(FLogFont,Sizeof(TLogFont),0);
With FlogFont do
begin
lfHeight:=Font.Height;
lfWidth:=0;
lfEscapement:=2700; //想旋转多少度,修改这里的参数就可以了啊
lforientation:=lfEscapement;
lfWeight:=Fw_Normal;
lfItalic:=0;
lfUnderline:=0;
lfStrikeOut:=0;
lfCharSet:=Ansi_CHARSET;
StrPCopy(lfFaceName,Font.Name);
lfQuality:=PROOF_QUALITY;
lfOutPrecision:=OUT_TT_ONLY_PRECIS;
lfClipPrecision:=CLIP_DEFAULT_PRECIS;
lfPitchAndFamily:=Variable_Pitch;
end;
Font.Handle:=CreateFontIndirect(FLogFont); Textout(x,y,'旋转文字');
TTF字体轮廓矢量数据
西安飞机工业公司设计部 朱朝阳 ------------------------------------------------------------------------------------ Windows系统的TTF字体具有字体优美、可无级缩放等优点,最适合应用在CAD类图形处理等软件中。直接分析TTF字体的文件格式并读出每个字的轮廓矢量是相当困难的,我们可以借助API函数来方便地获得这些数据。 ---- 调用函数GetGlyphOutline可以得到一个字的轮廓矢量或者位图。 ---- 函数原型如下: DWORD GetGlyphOutline(
HDC hdc, // 设备句柄
UINT uChar, // 将要读取的字符
UINT uFormat, // 返回数据的格式
LPGLYPHMETRICS lpgm, // GLYPHMETRICS结构地址
DWORD cbBuffer, // 数据缓冲区的大小
LPVOID lpvBuffer, // 数据缓冲区的地址
CONST MAT2 *lpmat2 // 转置矩阵的地址
);
---- 其中,参数uFormat取值如下: GGO_NATIVE - 要求函数返回字符的轮廓矢量数据;
GGO_METRICS - 函数仅返回GLYPHMETRICS结构至lpgm;
参数lpgm指向GLYPHMETRICS结构,该结构描述字符的位置。
参数lpmat2指向字符的转置矩阵。
---- 本文以下C++ Builder程序示范如何在画布上以指定的大小绘制字符串。 ---- 首先,建立一个新项目,在主窗口上放置一个Image控件,一个Edit控件,一个Button控件;然后,在Button的点击事件中加入如下代码: #include < stdlib.h >void __fastcall TForm1::Button1Click(TObject *Sender)
{
TRect ClipRect = Rect(0,0,Image1->Width,Image1->Height);
Image1->Picture = 0;
StretchTextRect(Image1->Canvas, ClipRect, Edit1->Text);
}---- 添加如下子程序: //---------------------
void TForm1::StretchTextRect(TCanvas
*pCanvas, TRect ClipRect, AnsiString Text)
{
pCanvas->Font->Size = 100;
pCanvas->Font->Name = “宋体";
pCanvas->Pen->Color = clBlack;
pCanvas->Pen->Mode = pmCopy;
pCanvas->Pen->Style = psSolid;
pCanvas->Pen->Width = 1;
int XSize = ClipRect.Width() / Text.Length();
int YSize = ClipRect.Height(); MAT2 mat2; // 转置矩阵,不用变换
mat2.eM11.value = 1;mat2.eM11.fract = 0;
mat2.eM12.value = 0;mat2.eM12.fract = 0;
mat2.eM21.value = 0;mat2.eM21.fract = 0;
mat2.eM22.value = 1;mat2.eM22.fract = 0; GLYPHMETRICS gm,gmm; // 首先获得字符的位置矩阵,存入gm
GetGlyphOutlineA(pCanvas->Handle,0x0b0a1,
GGO_METRICS,&gm,0,NULL,&mat2); char *ptr = Text.c_str();
TRect TheRect;
for(int i = 0;i < Text.Length();) {
int c1 = (unsigned char)*ptr;
int c2 = (unsigned char)*(ptr + 1);
UINT nChar;
TheRect.Left = i * XSize + ClipRect.Left;
TheRect.Top = ClipRect.Top;
TheRect.Right = (i + 2) * XSize + ClipRect.Left;
TheRect.Bottom = ClipRect.Top + YSize;
// 获得当前字符数据的数组的大小
DWORD cbBuffer = GetGlyphOutlineA(pCanvas->
Handle,nChar,GGO_NATIVE,&gmm,0,NULL,&mat2);
if(cbBuffer == GDI_ERROR) break;
void *lpBuffer = malloc(cbBuffer);
if(lpBuffer != NULL) {
// 读入数据置缓冲区
if(GetGlyphOutlineA(pCanvas->
Handle,nChar,GGO_NATIVE,
&gmm,cbBuffer,lpBuffer,&mat2) != GDI_ERROR) {
// 分析数据并绘制字符
TMemoryStream *MBuffer = new TMemoryStream();
MBuffer->Write(lpBuffer,cbBuffer);
MBuffer->Position = 0;
for(;MBuffer->Position < MBuffer->Size;) {
int CurPos = MBuffer->Position;
TTPOLYGONHEADER polyheader; int ptn = 0;
MBuffer->Read(&polyheader,sizeof(polyheader)); //读入头指针在头后面
ptn++;
for(int j = 0;j < (int)(polyheader.cb //头后的位置开始到头中记录的大小(头加记录)
- sizeof(polyheader));)
{
WORD wtype,cpfx;
MBuffer->Read(&wtype,sizeof(WORD)); //这里度的的是tpolycurve
MBuffer->Read(&cpfx,sizeof(WORD));
MBuffer->Position += cpfx * sizeof(POINTFX); //指针在一个记录的后面tpolyheader+tpolycurve+若干pointfx
j += sizeof(WORD) * 2 + cpfx * sizeof(POINTFX);//j是tpolycurve和后面跟的pointfx的总长度
if(wtype == TT_PRIM_LINE) ptn += cpfx; //若干如果是qspline那么点的数目要三倍?
else ptn += (cpfx - 1) * 3 + 1;
} TPoint *pts = new TPoint[ptn+1]; // 存储多边形顶点
MBuffer->Position = CurPos; //当前大记录的开始位置
ptn = 0;
MBuffer->Read(&polyheader,sizeof(polyheader)); //读头,指针在头后面
TPoint pt0 = POINTFX2TPoint(polyheader.pfxStart,TheRect,&gm);
pts[ptn++] = pt0; //头位置 点 ptn=1
for(int j = 0;j < (int)(polyheader.cb - sizeof(polyheader));) {
TPoint pt1;
WORD wtype,cpfx;
MBuffer->Read(&wtype,sizeof(WORD));
MBuffer->Read(&cpfx,sizeof(WORD)); //指针在tpolycurve的pointfx位置
POINTFX *pPfx = new POINTFX[cpfx];
MBuffer->Read((void *)pPfx,cpfx * sizeof(POINTFX));
j += sizeof(WORD) * 2 + cpfx * sizeof(POINTFX); //j到了大记录的尾位置
//处理读来的点数组记录
if(wtype == TT_PRIM_LINE) { // 直线段
for(int i = 0;i < cpfx;i++) {
pt1 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
pts[ptn++] = pt1;
}
}
else { // Bezier曲线
TPoint p0,p1,p2,p3,p11,p22,pp0,pp1,pp2,pt11,pt22;
int i;
for(i = 0;i < cpfx-1;i++) {
pt11 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
pt22 = POINTFX2TPoint(pPfx[i+1],TheRect,&gm);
pp0 = pts[ptn-1];
pp1 = pt11;
pp2.x = (pt11.x + pt22.x)/2;
pp2.y = (pt11.y + pt22.y)/2; p0 = pp0;
p1.x = pp0.x/3 + 2 * pp1.x/3;
p1.y = pp0.y/3 + 2 * pp1.y/3;
p2.x = 2 * pp1.x/3 + pp2.x/3;
p2.y = 2 * pp1.y/3 + pp2.y/3;
p3 = pp2; for(float t = 0.0f;t <= 1.0f;t += 0.5f) {
float x = (1-t)*(1-t)*(1-t)*p0.x+
3*t*(1-t)*(1-t)*p1.x+ 3*t*t
*(1-t)*p2.x + t*t*t*p3.x;
float y = (1-t)*(1-t)*(1-t)*p0.y
+ 3*t*(1-t)*(1-t)*p1.y+3
*t*t*(1-t)*p2.y + t*t*t*p3.y;
pts[ptn].x = x;
pts[ptn].y = y;
ptn++;
}
}
pt1 = POINTFX2TPoint(pPfx[i],TheRect,&gm);
pts[ptn++] = pt1;
}
delete pPfx;
}
pts[ptn] = pts[0]; // 封闭多边形
pCanvas->Brush->Color = clWhite;
pCanvas->Pen->Mode = pmXor;
pCanvas->Pen->Style = psClear;
pCanvas->Brush->Style = bsSolid;
pCanvas->Polygon(pts,ptn); delete pts;
}
delete MBuffer;
}
free(lpBuffer);
}
}
}
//---------------------
TPoint TForm1::POINTFX2TPoint(POINTFX pf,
TRect TheRect,GLYPHMETRICS *gm)
{
TPoint point;
float fx,fy;
fx = pf.x.value + pf.x.fract / 65536.0f + 0.5f;
fx = fx
/ (float)(gm->gmBlackBoxX + gm->gmptGlyphOrigin.x)
* (float)TheRect.Width() + (float)TheRect.Left;
fy = pf.y.value + pf.y.fract / 65536.0f + 0.5f;
fy = ((float)gm->gmBlackBoxY - fy)
/ (float)(gm->gmBlackBoxX + gm->gmptGlyphOrigin.x)
* (float)TheRect.Height() + (float)TheRect.Top;
point.x = int(fx);
point.y = int(fy);
return point;
}