www.gusucode.com > VC++编程实现获取字体的外框信息-源码程序 > VC++编程实现获取字体的外框信息-源码程序\code\UVectorFontView.cpp

    // UVectorFontView.cpp : implementation of the CUVectorFontView class
// Donwload by http://www.NewXing.com
/////////////////////////////////////////////////////////////////////
//作者:项坚煜(浙江工业大学信息工程学院)
//联系方式: QQ 125422950
//          e_mail unfirewood@etang.com
//
//
//
////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "UVectorFont.h"

#include "UVectorFontDoc.h"
#include "UVectorFontView.h"

#include "UTextInputDlg.h"
#include "math.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView

IMPLEMENT_DYNCREATE(CUVectorFontView, CView)

BEGIN_MESSAGE_MAP(CUVectorFontView, CView)
	//{{AFX_MSG_MAP(CUVectorFontView)
	ON_COMMAND(ID_TEXT_INPUT, OnTextInput)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView construction/destruction

CUVectorFontView::CUVectorFontView()
{
	// TODO: add construction code here
    m_sTextEdit = "";
    m_iFontHeight = 0;
    m_iFontSpace = 0;
    m_sFontFaceName = "";

}

CUVectorFontView::~CUVectorFontView()
{
}

BOOL CUVectorFontView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView drawing

void CUVectorFontView::OnDraw(CDC* pDC)
{
	CUVectorFontDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

    drawOutLine(pDC);


}

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView printing

BOOL CUVectorFontView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CUVectorFontView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CUVectorFontView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView diagnostics

#ifdef _DEBUG
void CUVectorFontView::AssertValid() const
{
	CView::AssertValid();
}

void CUVectorFontView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CUVectorFontDoc* CUVectorFontView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CUVectorFontDoc)));
	return (CUVectorFontDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CUVectorFontView message handlers

void CUVectorFontView::OnTextInput() 
{
    CDC *pDC=GetDC();

	CUTextInputDlg dlg;
    if (dlg.DoModal() == IDOK)
    {
        m_sTextEdit = dlg.getsTextEdit();
        m_iFontHeight = dlg.getiFontHeight();
        m_iFontSpace = dlg.getiFontSpace();
        m_sFontFaceName = dlg.getsFontFaceName();
        Invalidate();
    }
	ReleaseDC(pDC);
}

FIXED CUVectorFontView::FloatToFixed( double d )
{
	long l;
	l = (long)(d * 65536L);
	return *(FIXED *)&l;
}

int CUVectorFontView::mapFXY(FIXED fxy)
{
	long   lxy;
	lxy = *(LONG *)&fxy;
	return (int)((double)(lxy)/65536.0);
}

void CUVectorFontView::drawOutLine(CDC *pDC)
{
    if (m_sTextEdit.IsEmpty())
        return;

	DWORD dwSize;
	HANDLE hMem;
	LPTTPOLYGONHEADER lpph;
	LPBYTE lpb;
	long cbOutline, cbTotal;
        
	MAT2 m2;
	GLYPHMETRICS gm;         
	TEXTMETRIC tm;

    CFont font;
	VERIFY(font.CreateFont(
	   m_iFontHeight,             // nHeight
	   0,                         // nWidth
	   0,                         // nEscapement
	   0,                         // nOrientation
	   FW_NORMAL,                 // nWeight
	   FALSE,                     // bItalic
	   FALSE,                     // bUnderline
	   0,                         // cStrikeOut
	   ANSI_CHARSET,              // nCharSet
	   OUT_DEFAULT_PRECIS,        // nOutPrecision
	   CLIP_DEFAULT_PRECIS,       // nClipPrecision
	   DEFAULT_QUALITY,           // nQuality
	   DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
	   m_sFontFaceName)); 
	CFont* pOldFont=pDC->SelectObject(&font);
    pDC->SelectObject(&font);
	pDC->GetTextMetrics(&tm);

	m2.eM11 = FloatToFixed(1.0);
	m2.eM12 = FloatToFixed(0.0);
	m2.eM21 = FloatToFixed(0.0);
	m2.eM22 = FloatToFixed(1.0);

    //replace above code with follow code, there will be a surprise
/*  #define quartpi 3.1415926/4
    m2.eM11 = FloatToFixed(cos(quartpi));
	m2.eM12 = FloatToFixed(sin(quartpi));
	m2.eM21 = FloatToFixed(-sin(quartpi));
	m2.eM22 = FloatToFixed(cos(quartpi));
    
    // or 
/*  m2.eM11 = FloatToFixed(1.0);
	m2.eM12 = FloatToFixed(0);
	m2.eM21 = FloatToFixed(0.5);
	m2.eM22 = FloatToFixed(1);
*/
	int nChar = 0;  
    int x = 50; //startposition x-coordinate
    int y = 150; //startposition y-corrdinate
    for (int i = 0; i < m_sTextEdit.GetLength(); i++)
    {
        if (m_sTextEdit.GetAt(i) >= 0) //deal singlebyte char or multibyte char
            nChar = m_sTextEdit.GetAt(i);
        else
        {
            int th = m_sTextEdit.GetAt(i);
            int tl = m_sTextEdit.GetAt(i + 1);
            nChar = ((th & 0x00ff)<<8) + (tl & 0x00ff);
            i++;
        }
   
        CPen newpen;
        newpen.CreatePen(PS_DASHDOTDOT, 1, RGB(0,0,255));
        pDC->SelectObject(&newpen);
		dwSize = pDC->GetGlyphOutline(nChar,GGO_NATIVE,&gm,0L,NULL,&m2); //get the size of outline-information
		hMem=GlobalAlloc(GHND,dwSize);
		lpph=(LPTTPOLYGONHEADER)GlobalLock(hMem);
		pDC->GetGlyphOutline(nChar,GGO_NATIVE,&gm,dwSize,lpph,&m2); //get outline-line
		cbTotal = dwSize;
    
		while( cbTotal > 0 )
		{
			int xOld = mapFXY( lpph->pfxStart.x );
			int yOld = mapFXY( lpph->pfxStart.y );
            pDC->MoveTo(x+xOld, y-yOld );
			lpb   = (LPBYTE)lpph + sizeof(TTPOLYGONHEADER);
			cbOutline = (long)lpph->cb - sizeof(TTPOLYGONHEADER);
        
			while( cbOutline > 0 )
			{
				int  n;
				LPTTPOLYCURVE lpc;
				lpc = (LPTTPOLYCURVE)lpb;                                 
                drawOutLine(pDC,lpc->wType,lpc->cpfx,lpc->apfx, x, y);	//draw outline			
				n = sizeof(TTPOLYCURVE) + sizeof(POINTFX) * (lpc->cpfx - 1);
				lpb += n;
				cbOutline -= n;
			}                   

			pDC->LineTo(x+xOld,y-yOld);
			cbTotal -= lpph->cb;
			lpph     = (LPTTPOLYGONHEADER)lpb;
		}

	    GlobalUnlock(hMem);
	    GlobalFree(hMem);

        x += gm.gmCellIncX;  //control the next char position
        x += m_iFontSpace;
        y += gm.gmCellIncY;
    //  y += 50 * sin(x / 10);
    }
    pDC->SelectObject(pOldFont);
}

void CUVectorFontView::drawOutLine(CDC *pDC,int wType,int cpfx, POINTFX apfx[], int x, int y)
{
    CPoint lpPoint[1000];
	CPoint bezi[2];
    int i;
	for (i=0; i <cpfx;i++) 
	{
		lpPoint[i].x = x + mapFXY( apfx[i].x );
	    lpPoint[i].y = y - mapFXY( apfx[i].y );
	}
	switch (wType)
	{
	case TT_PRIM_LINE:
		for (i=0 ;i <cpfx;i++)
        {
			pDC->LineTo(lpPoint[i]); //you can replace lineto with polylineto, and so on
        }
        //pDC->PolylineTo(lpPoint,cpfx);
		break;
	case TT_PRIM_QSPLINE:
		for (i=0 ;i<cpfx;i++)   //if you replace lineto with curveto, it will be better
		    pDC->LineTo(lpPoint[i]);			
		break;
	default:
		MessageBox("字体不支持");
		break;
	}

}