发信人: softlag()
整理人: justice(2000-08-22 02:14:27), 站内信件
|
void Paint(CDC* pDC);
void DrawTTFOutline(CDC* pDC, UINT uChar, int x, int y, int ascent);
int FixedToInt(FIXED f);
FIXED fxDiv2(FIXED fxVal1, FIXED fxVal2);
void Paint(CDC* pDC)
{
CFont curFont;
curFont.CreateFont(60, 0, 0, 0, 400, false, false, 0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH&FF_SWISS,
"黑体" );
CFont* pOldFont=(CFont*)pDC->SelectObject(&curFont);
TEXTMETRIC tm;
int x=0, y=0;
pDC->GetTextMetrics(&tm);
DrawTTFOutline(pDC, '软', 0, 100, tm.tmAscent);
DrawTTFOutline(pDC, '体', 120, 100, tm.tmAscent);
DrawTTFOutline(pDC, '垃', 240, 100, tm.tmAscent);
DrawTTFOutline(pDC, '圾', 360, 100, tm.tmAscent);
pDC->SelectObject(pOldFont);
}
void DrawTTFOutline(CDC* pDC, UINT uChar, int x, int y, int ascent)
{
GLYPHMETRICS gm;
MAT2 mat;
DWORD dwMemSize; //所需内存空间大小
HGLOBAL hMem; //内存句柄
LPSTR pdwMemBits; //分配的内存 字体外形信息就保存在这段内存中
//分配内存空词
dwMemSize=pDC->GetGlyphOutline(uChar, GGO_NATIVE, &gm, 0, NULL, &mat) ;
hMem=GlobalAlloc(GHND, dwMemSize);
if( hMem==NULL )
{
TRACE("分配内存失败!\n");
return;
}
//锁定内存 因为我们要读取这段内存中的数据
pdwMemBits=(LPSTR)GlobalLock(hMem);
if( pdwMemBits==NULL )
{
TRACE("锁定内存失败!\n");
return;
}
//获取字体外形信息
if( pDC->GetGlyphOutline(uChar, GGO_NATIVE, &gm, dwMemSize, pdwMemBit s, &mat)!=dwMemSize)
{
TRACE("获取字体外形信息失败!\n");
return;
}
//设置pDC环境准备绘制uChar
CBrush curBrush(RGB(0, 0, 0));
CBrush* pOldBrush=pDC->SelectObject(&curBrush);
CPoint oldOrg=pDC->GetViewportOrg();
pDC->OffsetViewportOrg( x, y + ascent);
//以下是如何取得字体外形的代码
LPTTPOLYGONHEADER lpHeader;
LPTTPOLYGONHEADER lpStart;
LPTTPOLYCURVE lpCurve;
POINT Points[500];
int nOutlinePt[50]; //每个独立封闭框中的转折点数
int nTotal = 0; //转折点的共和.
int nInOutline; //当前外框曲线中的转折点数
int nOutline = 0; //字体外形中独立的封闭框的数目
int nFirstOutline; //第一条线的起始位置
int i;
POINTFX spline[3];
lpHeader=(LPTTPOLYGONHEADER)pdwMemBits;
lpStart=lpHeader;
while((DWORD)lpHeader < (DWORD)(((LPSTR)lpStart) + dwMemSize))//循 环直到读完内存中的字形数据
{
if(lpHeader->dwType == TT_POLYGON_TYPE)
{
nInOutline = 0;
//得到第一个外框曲线的地址
lpCurve = (LPTTPOLYCURVE)(lpHeader + 1);
nFirstOutline = nTotal;
while ((DWORD)lpCurve<(DWORD)(((LPSTR)lpHeader)+lpHeader->cb))//循环 直到取完当前外框中的点
{
//直线
if (lpCurve->wType==TT_PRIM_LINE)
{
for (i = 0; i<lpCurve->cpfx; i++)
{
Points[nTotal].x=FixedToInt(lpCurve->apfx[i].x);
Points[nTotal].y=FixedToInt(lpCurve->apfx[i].y);
nTotal++;
nInOutline++;
}
}
//曲线 (曲线是一个二次B样条)
else if (lpCurve->wType==TT_PRIM_QSPLINE)
{
spline[0]=*(LPPOINTFX)((LPSTR)lpCurve-sizeof(POINTFX));
for (i = 0; i<lpCurve->cpfx;)
{
spline[1]=lpCurve->apfx[i++];
if (i==(lpCurve->cpfx-1))
{
spline[2]=lpCurve->apfx[i++];
}
else
{
spline[2].x=fxDiv2(lpCurve->apfx[i-1].x, lpCurve->apfx[i].x);
spline[2].y=fxDiv2(lpCurve->apfx[i-1].y, lpCurve->apfx[i].y );
}
Points[nTotal].x=FixedToInt(spline[1].x);
Points[nTotal].y=FixedToInt(spline[1].y);
nTotal++;
Points[nTotal].x=FixedToInt(spline[2].x);
Points[nTotal].y=FixedToInt(spline[2].y);
nTotal++;
nInOutline+=2;
spline[0]=spline[2];
}
}
else
; //除了直线和曲线还有什么线呢?出错!
//指向下一条线
lpCurve = (LPTTPOLYCURVE)&(lpCurve->apfx[i]);
}
//增加一个点封闭当前外框.
Points[nTotal].x = FixedToInt(lpHeader->pfxStart.x)
Points[nTotal].y = FixedToInt(lpHeader->pfxStart.y);
nInOutline++;
nTotal++;
Points[nTotal].x = Points[nFirstOutline].x;
Points[nTotal].y = Points[nFirstOutline].y;
nInOutline++;
nTotal++;
nOutlinePt[nOutline++] = nInOutline;
//指向下一个外框.
lpHeader = (LPTTPOLYGONHEADER)(((LPSTR)lpHeader) + lpHeader->cb );
}
else
; //出错!
}
for (i = 0; i < nTotal; i++)
Points[i].y=0-Points[i].y;
//好了 点全部已经保存到Points中了 现在该做的是……
i=0;
pDC->SelectStockObject(BLACK_PEN);
for(int a=0; a<nOutline; a++)
{
pDC->MoveTo(Points[i]);
for(int b=0; b<nOutlinePt[a]; b++)
{
pDC->LineTo(Points[i]);
i++;
}
}
pDC->SetViewportOrg( oldOrg.x, oldOrg.y );
pDC->SelectObject( pOldBrush );
GlobalUnlock(hMem);
GlobalFree(hMem);
}
//一种将FIXED转换为INT最笨的方法
int FixedToInt(FIXED f)
{
int value=0x8000*2*f.value+f.fract;
value/=500;//这里的500为字体大小的比例因子 你可以改变它从而缩放字体
return value;
}
FIXED fxDiv2(FIXED fxVal1, FIXED fxVal2)
{
long l;
l = (*((long far *)&(fxVal1)) + *((long far *)&(fxVal2)))/2;
return(*(FIXED *)&l);
}
-- 写了这么多 但愿没有错别字
http:://softlag.yeah.net
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.128.240.88]
|
|