⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
 *	@doc	INTERNAL
 *
 *	@module FONT.C -- font cache |
 *
 *		includes font cache, char width cache;
 *		create logical font if not in cache, look up
 *		character widths on an as needed basis (this
 *		has been abstracted away into a separate class
 *		so that different char width caching algos can
 *		be tried.) <nl>
 *		
 *	Owner: <nl>
 *		David R. Fulmer <nl>
 *		Christian Fortini <nl>
 *		Jon Matousek <nl>
 *
 *	History: <nl>
 *		7/26/95		jonmat	cleanup and reorganization, factored out
 *					char width caching code into a separate class.
 *
 */								 

#include "_common.h"
#include "_font.h"
#include "_rtfconv.h"	// Needed for GetCodePage
#include <intsafe.h>

#define CLIP_DFA_OVERRIDE   0x40	//  Used to disable Korea & Taiwan font association


ASSERTDATA

// corresponds to yHeightCharPtsMost in richedit.h
#define yHeightCharMost 32760

// NOTE: this is global across all instances in the same process.
static CFontCache *__fc;

WCHAR	lfJapaneseFaceName[LF_FACESIZE];
WCHAR	lfHangulFaceName[LF_FACESIZE];
WCHAR	lfBig5FaceName[LF_FACESIZE];
WCHAR	lfGB2312FaceName[LF_FACESIZE];

/*
 *	InitFontCache ()
 *	
 *	@mfunc
 *		Initializes font cache.
 *
 *	@devnote
 *		This is exists so reinit.cpp doesn't have to know all about the 
 *		font cache.
 */
BOOL InitFontCache()
{
	// GuyBark Jupiter: Beware of oom.

	if(!(__fc = new CFontCache))
	{
	    return FALSE;
	}

    __fc->Init();

    return TRUE;
}

/*
 *	FreeFontCachet ()
 *	
 *	@mfunc
 *		Frees font cache.
 *
 *	@devnote
 *		This is exists so reinit.cpp doesn't have to know all about the 
 *		font cache.
 */
void FreeFontCache()
{
	__fc->Free();
	delete __fc;
	__fc = NULL;
}


/*
 *	CFontCache & fc()
 *	
 *	@func
 *		initialize the global __fc.
 *	@comm
 *		current #defined to store 16 logical fonts and
 *		respective character widths.
 *		
 */
CFontCache & fc()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "fc");
    return *__fc;
}

// ===================================  CFontCache  ====================================


/*
 *	CFontCache::Init ()
 *	
 *	@mfunc
 *		Initializes font cache.
 *
 *	@devnote
 *		This is not a constructor because something bad seems to happen
 *		if we try to contruct a global object.
 */
void CFontCache::Init ()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CFontCache::CFontCache");

	_dwAgeNext = 0;
}

/*
 *	CFontCache::Free ()
 *	
 *	@mfunc
 *		Frees resources attached to font cache.
 *
 *	@devnote
 *		This is not a constructor because something bad seems to happen
 *		if we try to call a destructor on a global object.
 */
void CFontCache::Free ()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CFontCache::~CFontCache");
}


/*
 *	CCcs* CFontCache::GetCcs(hdc, pcf, lZoomNumerator, lZoomDenominator, yPixelsPerInch)
 *	
 *	@mfunc
 *		Search the font cache for a matching logical font and return it.
 *		If a match is not found in the cache,  create one.
 *
 *	@rdesc
 *		A logical font matching the given CHARFORMAT info.
 */
CCcs* CFontCache::GetCcs(
	HDC			hdc,				//@parm HDC into which font will be selected
	const CCharFormat *const pcf,	//@parm description of desired logical font
	const LONG lZoomNumerator,		//@parm Zoom numerator for getting display font
	const LONG lZoomDenominator,	//@parm Zoom denominator for getting
	const LONG yPerInch)			//@parm Y pixels per inch
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CFontCache::GetCcs");
	CLock	lock;

									//  display font
	const CCcs * const	pccsMost = &_rgccs[cccsMost - 1];
	CCcs *				pccs;
    LONG				lfHeight;

    BYTE				bCrc;
	SHORT				hashKey;
	// Duplicate the format structure because we might need to change some of the
	// values by the zoom factor 
	// and in the case of sub superscript
	CCharFormat cf = *pcf;


	//FUTURE igorzv
	//Take subscript size, subscript offset, superscript offset, superscript size 
	// from the OUTLINETEXMETRIC


	// change cf.yHeight in the case of sub superscript
	if (cf.dwEffects & (CFE_SUPERSCRIPT | CFE_SUBSCRIPT))
	{  
	     if (cf.dwEffects & CFE_SUBSCRIPT)
		 {  
		 	cf.yOffset-=cf.yHeight/5;
		 }
		 else
		 {
 		 	cf.yOffset += cf.yHeight/2;	 
		 }
	 	 cf.yHeight = 2*cf.yHeight/3;
	}					   

	// We only adjust the size if we need to.
	if (lZoomNumerator != lZoomDenominator)
	{
		cf.yHeight = MulDiv(cf.yHeight, lZoomNumerator, lZoomDenominator);
		cf.yOffset = MulDiv(cf.yOffset, lZoomNumerator, lZoomDenominator);
	}

	// calculate lfHeight used for Compare().
	lfHeight = -MulDiv(cf.yHeight, yPerInch, LY_PER_INCH);

	bCrc = cf.bCRC;

	Assert(0 != bCrc);								// Wasn't computed?

	if(!lfHeight)
		lfHeight--;	// round error, make this a minimum legal height of -1.

	// check our hash before going sequential.
	hashKey = bCrc & QUICKCRCSEARCHSIZE;
	if ( bCrc == quickCrcSearch[hashKey].bCrc )
	{
		pccs = quickCrcSearch[hashKey].pccs;
		if(pccs && pccs->_bCrc == bCrc && pccs->_fValid )
		{
	        if(pccs->Compare( &cf, lfHeight ))
			{
                goto matched;
			}
		}
	}
	quickCrcSearch[hashKey].bCrc = bCrc;

	// squentially search ccs for same character format
	for(pccs = &_rgccs[0]; pccs <= pccsMost; pccs++)
	{
		if( pccs->_bCrc == bCrc && pccs->_fValid )
		{
	        if(!pccs->Compare( &cf, lfHeight ))
                continue;
		matched:
			//$ FUTURE: make this work even with wrap around of dwAgeNext
			// Mark as most recently used if it isn't already in use.
			if(pccs->_dwAge != _dwAgeNext - 1)
				pccs->_dwAge = _dwAgeNext++;
			pccs->_dwRefCount++;		// bump up ref. count

			// setup the font to be used for this hdc.
			pccs->_hdc = hdc;

			// the same font can be used at different offsets.
			pccs->_yOffset = cf.yOffset ? (cf.yOffset * yPerInch / LY_PER_INCH) : 0;

			quickCrcSearch[hashKey].pccs = pccs;

			return pccs;
		}
	}

	// we did not find a match, init a new font cache.
	pccs = GrabInitNewCcs ( hdc, &cf, yPerInch );

	quickCrcSearch[hashKey].pccs = pccs;

	return pccs;
}

/*
 *	CCcs* CFontCache::GrabInitNewCcs(hdc, pcf)
 *	
 *	@mfunc
 *		create a logical font and store it in our cache.
 *		
 */
CCcs* CFontCache::GrabInitNewCcs(
	HDC hdc,						//@parm HDC into which font will be selected
	const CCharFormat * const pcf,	//@parm description of desired logical font
	const LONG yPerInch)			//@parm Y Pixels per Inch
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CFontCache::GrabInitNewCcs");

	DWORD				dwAgeOldest = 0xffffffff;
	CCcs *				pccs;
	const CCcs * const	pccsMost = &_rgccs[cccsMost - 1];
	CCcs *				pccsOldest = NULL;

	// look for unused entry and oldest in use entry
	for(pccs = &_rgccs[0]; pccs <= pccsMost && pccs->_fValid; pccs++)
		if(pccs->_dwRefCount == 0 && pccs->_dwAge < dwAgeOldest)
		{
			dwAgeOldest = pccs->_dwAge;
			pccsOldest = pccs;
		}

	if(pccs > pccsMost)		// Didn't find an unused entry, use oldest entry

	{
		pccs = pccsOldest;
		if(!pccs)
		{
			AssertSz(FALSE, "CFontCache::GrabInitNewCcs oldest entry is NULL");
			return NULL;
		}
	}

	pccs->_pfc = this;
	
	// Initialize new CCcs
	if(!pccs->Init(hdc, pcf, yPerInch) )
	{
		return NULL;
	}

	pccs->_dwRefCount++;

	return pccs;
}

// =============================  CCcs  class  ===================================================


/*
 *	BOOL CCcs::Init()
 *	
 *	@mfunc
 *		Init one font cache object. The global font cache stores
 *		individual CCcs objects. 
 */
BOOL CCcs::Init (
	HDC hdc,						//@parm HDC into which font will be selected
	const CCharFormat * const pcf,	//@parm description of desired logical font
	const LONG yPerInch)			//@parm Y pixels per inch
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::Init");

	if ( _fValid ) Free();				// recycle already in-use fonts.


	if( MakeFont(hdc, pcf, yPerInch) )
	{
		_bCrc = pcf->bCRC;
		_yCfHeight = pcf->yHeight;

		Assert(0 != _bCrc);

		if( pcf->yOffset )				// offset for super/sub script.
		{
			_yOffset = pcf->yOffset * yPerInch / LY_PER_INCH;
		}
		else
			_yOffset = 0;
	
		_dwAge = _pfc->_dwAgeNext++;

		_fValid = TRUE;			// successfully created a new font cache.

	}

	return _fValid;
}

/*
 *	void CCcs::Free ()
 *	
 *	@mfunc
 *		Free any dynamic memory allocated by an individual font's cache.
 *		
 */
void CCcs::Free ()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::Free");

	Assert(_fValid);

	_widths.Free();

	if(_hfont)
		DestroyFont();

	_fValid = FALSE;
	_dwRefCount = 0;
}

/*
 *	BOOL CCcs::CheckFillWidths ()
 *	
 *	@mfunc
 *		Check existence, load nonexistent width information.
 */
BOOL CCcs::CheckFillWidths (
	TCHAR ch, 			//@parm	the TCHAR character in question.
	LONG &rlWidth )	 	//@parm the width to use
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::CheckFillWidths");

	if ( !_widths.CheckWidth(ch, rlWidth) )
	{
		return FillWidths(ch, rlWidth);
	}

	return TRUE;
}

/* 	
 *	CCcs::FillWidths (ch, rlWidth)
 *
 *	@mfunc
 *		Fill in this CCcs with metrics info for given device
 *
 *	@rdesc
 *		TRUE if OK, FALSE if failed
 */
BOOL CCcs::FillWidths(
	TCHAR ch, 		//@parm The TCHAR character we need a width for.
	LONG &rlWidth)	//@parm the width of the character
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::FillWidths");

	BOOL		fRes = FALSE;
	HFONT		hfontOld;

	AssertSz(_hfont, "CCcs::Fill - CCcs has no font");


	//	The mapping mode for the HDC is set before we get here.
	hfontOld = (HFONT)GetCurrentObject( _hdc, OBJ_FONT );
    if ( hfontOld == _hfont || (hfontOld = (HFONT)SelectObject(_hdc, _hfont)) )
    {
		// fill up the width info.
		fRes = _widths.FillWidth ( _hdc, ch, _xOverhangAdjust, rlWidth, 
			_wCodePage, _bConvertMode, _xAveCharWidth, _xDefDBCWidth, _fFixPitchFont );
    }
    
	//	restore the original mapping mode and font.
	//
	if(hfontOld && hfontOld != _hfont)
		SelectFont(_hdc, hfontOld);

	return fRes;
}

/* 	
 *	BOOL CCcs::MakeFont(hdc, pcf)
 *
 *	@mfunc
 *		Wrapper, setup for CreateFontIndirect() to create the font to be
 *		selected into the HDC.
 *
 *	@rdesc
 *		TRUE if OK, FALSE if allocation failure 
 */

#define szFontOfChoice TEXT("Arial")

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -