349 lines
8.3 KiB
C++
349 lines
8.3 KiB
C++
//
|
|
// Simple font classes with helper functions.
|
|
//
|
|
// (C) Microsoft Corp.
|
|
// Felix Andrew 1999
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "fonts.h"
|
|
|
|
void CQuickFont::Init(HFONT hf)
|
|
{
|
|
if(GetFont())
|
|
{
|
|
DeleteObject(GetFont());
|
|
m_font=NULL;
|
|
m_baseUnit=0;
|
|
}
|
|
|
|
//
|
|
// Select the font into the DC
|
|
//
|
|
m_font=hf; // CreateFontIndirect(&lf);
|
|
SelectObject(GetDC(), m_font );
|
|
m_baseUnit=0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
CQuickFont::CQuickFont(LPTSTR name, DWORD dwSize)
|
|
: m_font(NULL), m_dc(NULL)
|
|
{
|
|
Init(name, dwSize);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
CQuickFont::~CQuickFont()
|
|
{
|
|
if(m_font)
|
|
DeleteObject(m_font);
|
|
if(m_dc)
|
|
ReleaseDC(NULL, m_dc);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Creates the font we require
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
void CQuickFont::Init(LPCTSTR name, DWORD dwSize )
|
|
{
|
|
Init( name, dwSize, 0, FW_NORMAL );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Creates the font we require
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
void CQuickFont::Init(LPCTSTR name, DWORD dwSize , DWORD dwStyle, DWORD dwWeight, LOGFONT * pBaseLF )
|
|
{
|
|
if(GetFont())
|
|
{
|
|
DeleteObject(GetFont());
|
|
m_font=NULL;
|
|
m_baseUnit=0;
|
|
}
|
|
|
|
LOGFONT lf;
|
|
|
|
if( ( (name==NULL) || (lstrcmpi(name,TEXT(""))==0) ) && (pBaseLF==NULL) )
|
|
return;
|
|
|
|
if(pBaseLF==NULL)
|
|
ZeroMemory( &lf, sizeof(LOGFONT));
|
|
else
|
|
CopyMemory( &lf, pBaseLF, sizeof( LOGFONT ) );
|
|
|
|
if( dwWeight )
|
|
lf.lfWeight=dwWeight;
|
|
|
|
if( dwStyle & FS_ITALIC )
|
|
lf.lfItalic=TRUE;
|
|
|
|
if( name )
|
|
lstrcpy(lf.lfFaceName, name );
|
|
|
|
if( dwSize )
|
|
{
|
|
lf.lfHeight = -MulDiv(dwSize, GetDeviceCaps(GetDC(), LOGPIXELSY), 72);
|
|
m_dwSize=dwSize;
|
|
}
|
|
else
|
|
{
|
|
// BUGBUG - size is inherited from the logfont?
|
|
}
|
|
|
|
//
|
|
// Select the font into the DC
|
|
//
|
|
m_font=CreateFontIndirect(&lf);
|
|
|
|
SelectObject(GetDC(), m_font );
|
|
m_baseUnit=0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Gets a screen DC so we can calculate the size of text rendered in this font
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
HDC CQuickFont::GetDC()
|
|
{
|
|
if(m_dc==NULL)
|
|
m_dc=::GetDC(NULL); // VadimG says this is OK
|
|
return m_dc;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Calculates the height of a piece of text, given the width of the text
|
|
// loword is the height
|
|
// hi-word is the width
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
SIZE CQuickFont::HowHigh(LPCTSTR text, DWORD dwWidth)
|
|
{
|
|
RECT rect={0};
|
|
rect.right=dwWidth;
|
|
rect.bottom=-1;
|
|
DrawText( GetDC(), text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
|
|
SIZE s;
|
|
s.cx=rect.right;
|
|
s.cy=rect.bottom;
|
|
return s;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Returns the length of the text, so caller can determin if multi line / single line>
|
|
// returns HEIGHT WIDTH
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
SIZE CQuickFont::HowLong( LPCTSTR text )
|
|
{
|
|
SIZE size;
|
|
GetTextExtentPoint32( GetDC(), text, lstrlen(text), &size);
|
|
// int width=0;
|
|
// int height=0;
|
|
// GetTextExtentExPoint( GetDC(), text, lstrlen(text), 0, &width, &height, &size );
|
|
return size;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Taken from NT5 user.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
DWORD CQuickFont::GetDialogBaseUnits()
|
|
{
|
|
if(m_baseUnit)
|
|
return m_baseUnit;
|
|
m_baseUnit = GetDialogBaseUnits( GetDC(), m_font );
|
|
return m_baseUnit;
|
|
}
|
|
|
|
DWORD CQuickFont::GetDialogBaseUnits( HDC hdc, HFONT font )
|
|
{
|
|
DWORD baseUnit;
|
|
TEXTMETRIC textMetric;
|
|
SelectObject(hdc, font );
|
|
GetTextMetrics( hdc, &textMetric);
|
|
|
|
if( textMetric.tmPitchAndFamily & TMPF_FIXED_PITCH )
|
|
{
|
|
SIZE size;
|
|
static CONST TCHAR wszAvgChars[] = TEXT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
int len=(sizeof(wszAvgChars) / sizeof(TCHAR)) - 1;
|
|
/*
|
|
* Change from tmAveCharWidth. We will calculate a true average
|
|
* as opposed to the one returned by tmAveCharWidth. This works
|
|
* better when dealing with proportional spaced fonts.
|
|
*/
|
|
if (GetTextExtentPoint32(hdc, wszAvgChars,len , &size))
|
|
{
|
|
// UserAssert((((size.cx / 26) + 1) / 2) > 0);
|
|
int p1=size.cx/26;
|
|
baseUnit = MAKELONG( ((size.cx / 26) + 1) / 2, size.cy); // round up
|
|
}
|
|
}
|
|
else
|
|
baseUnit = ::GetDialogBaseUnits();
|
|
return baseUnit;
|
|
}
|
|
|
|
SIZE CQuickFont::GetPixelsFromDlgUnits(SIZE s)
|
|
{
|
|
return GetPixelsFromDlgUnits( s, GetDialogBaseUnits() );
|
|
}
|
|
|
|
// Static, takes the base.
|
|
SIZE CQuickFont::GetPixelsFromDlgUnits(SIZE s, DWORD nBase)
|
|
{
|
|
SIZE r;
|
|
// r.cx= (s.cx * LOWORD(nBase)) / 4;
|
|
// r.cy= (s.cy * HIWORD(nBase)) / 8;
|
|
// USER does below, MSDN does above.
|
|
r.cx = MulDiv( s.cx, LOWORD(nBase), 4);
|
|
r.cy = MulDiv( s.cy, HIWORD(nBase), 8);
|
|
return r;
|
|
}
|
|
|
|
SIZE CQuickFont::GetDlgUnitsFromPixels(SIZE s)
|
|
{
|
|
return GetDlgUnitsFromPixels( s, GetDialogBaseUnits() );
|
|
}
|
|
|
|
SIZE CQuickFont::GetDlgUnitsFromPixels(SIZE s, DWORD nBase)
|
|
{
|
|
SIZE r;
|
|
// r.cx= s.cx * 4 / LOWORD(nBase) ;
|
|
// r.cy= s.cy * 8 / HIWORD(nBase) ;
|
|
// USER does below, MSDN does above.
|
|
r.cx = MulDiv( s.cx, 4, LOWORD(nBase) );
|
|
r.cy = MulDiv( s.cy, 8, HIWORD(nBase) );
|
|
return r;
|
|
}
|
|
|
|
|
|
void CQuickFont::GetLogFont( int cbSize, LOGFONT * pLF )
|
|
{
|
|
GetObject( m_font, cbSize, pLF );
|
|
}
|
|
|
|
#ifdef OLD_FONT_CODE
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
CFonts::CFonts()
|
|
: m_uiNum(0),
|
|
m_pFonts(NULL)
|
|
{
|
|
}
|
|
|
|
CFonts::~CFonts()
|
|
{
|
|
Init(0,0); // deletes and cleans up the fonts.
|
|
}
|
|
|
|
void CFonts::Init(UINT uiNumFonts, UINT uiType)
|
|
{
|
|
//
|
|
// Clean up old fonts.
|
|
//
|
|
if(m_pFonts)
|
|
{
|
|
UINT uiIndex;
|
|
for(uiIndex=0;uiIndex<m_uiNum;uiIndex++)
|
|
if(m_pFonts[uiIndex])
|
|
DeleteObject(m_pFonts[uiIndex]);
|
|
delete [] m_pFonts;
|
|
}
|
|
|
|
//
|
|
// Create new fonts.
|
|
//
|
|
if(uiNumFonts)
|
|
m_pFonts=new HFONT[uiNumFonts];
|
|
m_uiNum=uiNumFonts;
|
|
|
|
//
|
|
// Zero init them.
|
|
//
|
|
UINT uiIndex;
|
|
for(uiIndex=0;uiIndex<m_uiNum;uiIndex++)
|
|
m_pFonts[uiIndex]=NULL;
|
|
|
|
m_uiType=uiType;
|
|
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
void CFonts::CreateFont(UINT uiIndex, LONG lfWeight, BYTE lfItalic, BYTE lfStrike )
|
|
{
|
|
|
|
switch( m_uiType)
|
|
{
|
|
case ODT_MENU:
|
|
{
|
|
NONCLIENTMETRICS ncm;
|
|
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
|
|
{
|
|
LOGFONT lf;
|
|
CopyMemory(&lf, &(ncm.lfMenuFont), sizeof(ncm.lfMenuFont));
|
|
lf.lfWeight=lfWeight;
|
|
lf.lfItalic=lfItalic;
|
|
lf.lfStrikeOut=lfStrike;
|
|
SetFont( uiIndex, CreateFontIndirect(&lf) );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Not perhaps the above fails - do default.
|
|
//
|
|
default:
|
|
{
|
|
LOGFONT lf;
|
|
|
|
if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
|
|
{
|
|
lf.lfWeight=lfWeight;
|
|
lf.lfItalic=lfItalic;
|
|
lf.lfStrikeOut=lfStrike;
|
|
SetFont( uiIndex, CreateFontIndirect(&lf) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HFONT CFonts::GetFont(UINT iIndex)
|
|
{
|
|
if(iIndex>m_uiNum || !m_pFonts)
|
|
return NULL;
|
|
return m_pFonts[iIndex];
|
|
}
|
|
|
|
void CFonts::SetFont(UINT uiIndex, HFONT hf)
|
|
{
|
|
if(uiIndex>m_uiNum || !m_pFonts)
|
|
return;
|
|
|
|
if(m_pFonts[uiIndex])
|
|
DeleteObject(m_pFonts[uiIndex]);
|
|
|
|
m_pFonts[uiIndex]=hf;
|
|
}
|
|
#endif
|