[kaze's test] プログラミングメモ |
→目次 |
文字の輪郭を描画する方法(VC++)

TrueTypeフォントの文字の輪郭を取り出して、文字の輪郭だけを描画することができます。輪郭を取得するには、BOOL
BeginPath( )を使います。デバイス コンテキストのパス ブラケットを開きます。パス ブラケットを開いた後、アプリケーションは GDI
描画関数の呼び出しを開始し、パス内の点を定義(記録)できます。アプリケーションは
EndPath( ) メンバ関数を呼び出して開いたパス
ブラケットを閉じられます。
例:
void CDrawTextOutlineView::DrawOutlineOfText(CDC* pDC, CString strText)
{
CRect r;
GetClientRect(&r);
CDC dc;
//メモリDCを作ります。
BOOL bRet = dc.CreateCompatibleDC(pDC);
CBitmap bmpBack;
bRet = bmpBack.CreateCompatibleBitmap(pDC, r.right, r.bottom);
CBitmap* pOldBmp = dc.SelectObject(&bmpBack);
//やや大きめにフォントを設定しました。
CFont font;
LOGFONT logfont;
memset(&logfont, 0, sizeof(logfont));
logfont.lfHeight = 64;
logfont.lfWidth = 0;
logfont.lfWeight = 600;
logfont.lfCharSet = SHIFTJIS_CHARSET;
strcpy(logfont.lfFaceName, "MS P明朝");
font.CreateFontIndirect(&logfont);
CFont* pOldFont = dc.SelectObject(&font);
//メモリDC上の描画の記録を開始します。
dc.BeginPath();
dc.SetBkMode(TRANSPARENT);
//メモリDC上で文字列を描画します。
dc.TextOut(0, 0, strText);
//メモリDC上の描画の記録を終了します。
dc.EndPath();
//記録した描画情報の中にある曲線を直線(線分)に直す。
dc.FlattenPath();
//記録した描画情報の点数を取得します。
int nCount = dc.GetPath(NULL, NULL, 0);
if (nCount <= 0)
return;
LPPOINT lpPoints = new POINT [nCount];
LPBYTE lpTypes = new BYTE [nCount];
//記録した描画情報を取得します。
dc.GetPath(lpPoints, lpTypes, nCount);
//記録した描画情報を利用して、ViewのDCに線分を描画します。
POINT pntStart;
for (int i = 0; i < nCount; i ++)
{
//MoveToの描画
if (lpTypes[i] == PT_MOVETO)
{
pDC->MoveTo(lpPoints[i].x, lpPoints[i].y);
pntStart = lpPoints[i];
}
//LineToの描画
else if (lpTypes[i] == PT_LINETO)
{
pDC->LineTo(lpPoints[i].x, lpPoints[i].y);
}
//頭と末尾を繋ぐ
if (lpTypes[i] & PT_CLOSEFIGURE)
{
pDC->LineTo(pntStart.x, pntStart.y);
}
}
delete lpPoints;
delete lpTypes;
}
|