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

📄 font.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

BOOL CCcs::MakeFont(
	HDC hdc,						//@parm HDC into which  font will be selected
	const CCharFormat * const pcf,	//@parm description of desired logical font
	const LONG yPerInch)
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::MakeFont");

	_bConvertMode = pcf->bInternalEffects & CFEI_RUNISDBCS
				  ? CM_LOWBYTE : CM_NONE;

	_hdc = hdc;

	// Computes font height
	AssertSz(pcf->yHeight <= INT_MAX, "It's too big");

	//	Roundoff can result in a height of zero, which is bad.
	//	If this happens, use the minimum legal height.
	_lf.lfHeight = -(MulDiv(pcf->yHeight, yPerInch, LY_PER_INCH));
	if(_lf.lfHeight > 0)
		_lf.lfHeight = -_lf.lfHeight;		//FUTURE: do something more intelligent...
	if(!_lf.lfHeight)
		_lf.lfHeight--;	// round error, make this a minimum legal height of -1.
	_lf.lfWidth			= 0;

	if( pcf->wWeight != 0 )
	{
		_lf.lfWeight = pcf->wWeight;
	}
	else
	{
		_lf.lfWeight	= (pcf->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
		#ifdef MACPORTStyle
		_lf.lfWeight	|= (pcf->dwEffects & CFE_OUTLINE) ? FW_OUTLINE : _lf.lfWeight;
		_lf.lfWeight	|= (pcf->dwEffects & CFE_SHADOW) ? FW_SHADOW : _lf.lfWeight; 
		#endif
	}

	_lf.lfItalic		= (pcf->dwEffects & CFE_ITALIC)	!= 0;
	_lf.lfUnderline		= 0;	
	_lf.lfStrikeOut		= 0;
	_lf.lfCharSet		= _bConvertMode == CM_LOWBYTE ? ANSI_CHARSET : pcf->bCharSet;
	_lf.lfEscapement 	= 0;
	_lf.lfOrientation 	= 0;
	_lf.lfOutPrecision 	= OUT_DEFAULT_PRECIS;
	_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS | CLIP_DFA_OVERRIDE;
	_lf.lfQuality 		= DEFAULT_QUALITY;
	_lf.lfPitchAndFamily = pcf->bPitchAndFamily;

	// If the run is DBCS, that means the font's codepage is not available in
	// this system.  Use the English ANSI codepage instead so we will display
	// ANSI characters correctly.  NOTE: _wCodePage is only used for Win95.
	_wCodePage = (WORD)GetCodePage(_lf.lfCharSet);

	wcscpy(_lf.lfFaceName, pcf->szFaceName);

	_bUnderlineType = CFU_UNDERLINENONE;

	if ((pcf->dwEffects & CFE_UNDERLINE) != 0)
	{
		_bUnderlineType = CFU_UNDERLINE;

		if (pcf->bUnderlineType)
		{
			_bUnderlineType = pcf->bUnderlineType;
		}
	}

	_fStrikeOut = (pcf->dwEffects & CFE_STRIKEOUT) != 0;

	// Reader! A bundle of spagghetti code lies ahead of you!
	// But go on boldly, for these spagghetti are seasoned with 
	// lots of comments, and ... good luck to you...

	BOOL fTweakedCharSet = FALSE;

	HFONT hfontOriginalCharset = NULL;
	BYTE bOriginalCharset = _lf.lfCharSet;
	WCHAR szNewFaceName[LF_FACESIZE];

	if (NULL == GetFontWithMetrics(szNewFaceName))
	{
	    AssertSz(0, "GetFontWithMetrics failed");
	    return FALSE;
    }
    

	if (0 != wcscmp(szNewFaceName, _lf.lfFaceName))					
	{
		BOOL fCorrectFont = FALSE;

		if (_lf.lfCharSet == SYMBOL_CHARSET)					
		{
			// #1. if the face changed, and the specified charset was SYMBOL,
			//     but the face name exists and suports ANSI, we give preference
			//     to the face name

			_lf.lfCharSet = ANSI_CHARSET;
			fTweakedCharSet = TRUE;			

			hfontOriginalCharset = _hfont;
			GetFontWithMetrics(szNewFaceName);

			if (0 == wcscmp(szNewFaceName, _lf.lfFaceName))
				// that's right, ANSI is the asnwer
				fCorrectFont = TRUE;
			else
				// no, fall back by default
				// the charset we got was right
				_lf.lfCharSet = bOriginalCharset;
		}
		else if (_lf.lfCharSet == DEFAULT_CHARSET && _bCharSet == DEFAULT_CHARSET)
		{
			// #2. If we got the "default" font back, we don't know what it means
			// (could be anything) so we veryfy that this guy's not SYMBOL
			// (symbol is never default, but the OS could be lying to us!!!)
			// we would like to veryfy more like whether it actually gave us
			// Japanese instead of ANSI and labeled it "default"...
			// but SYMBOL is the least we can do

			_lf.lfCharSet = SYMBOL_CHARSET;
			wcscpy(_lf.lfFaceName, szNewFaceName);
			fTweakedCharSet = TRUE;			

			hfontOriginalCharset = _hfont;
			GetFontWithMetrics(szNewFaceName);

			if (0 == wcscmp(szNewFaceName, _lf.lfFaceName))
				// that's right, it IS symbol!
				// 'correct' the font to the 'true' one,
				//  and we'll get fMappedToSymbol
				fCorrectFont = TRUE;
				
			// always restore the charset name, we didn't want to
			// question he original choice of charset here
			_lf.lfCharSet = bOriginalCharset;

		}
		else if ( _bConvertMode != CM_LOWBYTE && IsFECharset(_lf.lfCharSet)
			&& (!OnWinNTFE() || !OnWin95FE()))
		{
			if (_bCharSet != _lf.lfCharSet && (VER_PLATFORM_WIN32_WINDOWS == dwPlatformId))
			{
				// on Win95, when rendering to PS driver,
				// it will give us something other than what we asked.
				// We have to try some known font we got from GDI
				switch (_lf.lfCharSet)
				{
					case CHINESEBIG5_CHARSET:
						wcscpy(_lf.lfFaceName, lfBig5FaceName);
						break;

					case SHIFTJIS_CHARSET:
						wcscpy(_lf.lfFaceName, lfJapaneseFaceName);
						break;

					case HANGEUL_CHARSET:
						wcscpy(_lf.lfFaceName, lfHangulFaceName);
						break;

					case GB2312_CHARSET:
						wcscpy(_lf.lfFaceName, lfGB2312FaceName);
						break;
				}
			}
			else
			{
				// this is a FE Font (from Lang pack) on a nonFEsystem
				wcscpy(_lf.lfFaceName, szNewFaceName);
			}
			hfontOriginalCharset = _hfont;		

			GetFontWithMetrics(szNewFaceName);

			if (0 == wcscmp(szNewFaceName, _lf.lfFaceName))
			{
				// that's right, it IS the FE font we want!
				// 'correct' the font to the 'true' one.
				fCorrectFont = TRUE;
//				if (VER_PLATFORM_WIN32_WINDOWS == dwPlatformId)
//				{
					// save up the GDI font names for later printing use
					switch (_lf.lfCharSet)
					{
						case CHINESEBIG5_CHARSET:
							wcscpy(lfBig5FaceName, _lf.lfFaceName);
							break;

						case SHIFTJIS_CHARSET:
							wcscpy(lfJapaneseFaceName, _lf.lfFaceName);
							break;

						case HANGEUL_CHARSET:
							wcscpy(lfHangulFaceName, _lf.lfFaceName);
							break;

						case GB2312_CHARSET:
							wcscpy(lfGB2312FaceName, _lf.lfFaceName);
							break;
					}
//				}
			}
			fTweakedCharSet = TRUE;
		}

		if (hfontOriginalCharset)
		{
		// either keep the old font or the new one		

			if (fCorrectFont)
			{
				DeleteObject(hfontOriginalCharset);
				hfontOriginalCharset = NULL;
			}
			else 
			{
				// fall back to the original font
				DeleteObject(_hfont);

				_hfont = hfontOriginalCharset;
				hfontOriginalCharset = NULL;
				
				GetTextMetrics();
			}
		}
	}

RetryCreateFont:
	{
		// could be that we just plain symply get mapped to symbol. 
		// avoid it
		BOOL fMappedToSymbol =	(_bCharSet == SYMBOL_CHARSET && 
								 _lf.lfCharSet != SYMBOL_CHARSET);

		BOOL fChangedCharset = (_bCharSet != _lf.lfCharSet && 
								_lf.lfCharSet != DEFAULT_CHARSET);

		if (fChangedCharset || fMappedToSymbol)
		{
			// Here, the system did not preserve the font language or mapped 
			// our non-symbol font onto a symbol font,
			// which will look awful when displayed.
			// Giving us a symbol font when we asked for a non-symbol one
			// (default can never be symbol) is very bizzare and means
			// that either the font name is not known or the system
			// has gone complete nuts here.
			// The charset language takes priority over the font name.
			// Hence, I would argue that nothing can be done to save the 
			// situation at this point, and we have to 
			// delete the font name and retry

			// let's tweak it a bit
			fTweakedCharSet = TRUE;

			if (0 == wcscmp(_lf.lfFaceName, szFontOfChoice))
			{
				// we've been here already
				// no font with an appropriate charset is on the system
				// try getting the ANSI one for the original font name
				// next time around, we'll null out the name as well!!
				if (_lf.lfCharSet == ANSI_CHARSET) 
				{
					TRACEINFOSZ("Asking for ANSI ARIAL and not getting it?!");

					// those Win95 guys have definitely outbugged me 
					goto GetOutOfHere;
				}

				DeleteObject(_hfont);
				wcscpy(_lf.lfFaceName, pcf->szFaceName);
				_lf.lfCharSet = ANSI_CHARSET;
				
			}
			else
			{
				DeleteObject(_hfont);
				wcscpy(_lf.lfFaceName, szFontOfChoice);
			}

			GetFontWithMetrics(szNewFaceName);
			goto RetryCreateFont;
		}

    }

GetOutOfHere:
	if(fTweakedCharSet || _bConvertMode == CM_LOWBYTE)
	{
		// we must preserve the original charset value, since it is used in Compare()
		_lf.lfCharSet = bOriginalCharset;
		wcscpy(_lf.lfFaceName, pcf->szFaceName);
	}

	if (hfontOriginalCharset)
		DeleteObject(hfontOriginalCharset);
   
	// if we're really really stuck, just get the system font and hope for the best.
	if( _hfont == 0 )
	{
		_hfont = (HFONT)GetStockObject(SYSTEM_FONT);
	}
	return _hfont != 0;
}

/*
 *	BOOL CCcs::GetFontWithMetrics (szNewFaceName)
 *	
 *	@mfunc
 *		Get metrics used by the measurer and renderer and the new face name.
 */
BOOL CCcs::GetFontWithMetrics (
	WCHAR* szNewFaceName)
{

	// we want to keep _lf untouched as it is used in Compare().
	_hfont = CreateFontIndirect(&_lf);

    if (_hfont)
    {
		// FUTURE (alexgo) if a font was not created then we may want to select 
		//		a default one.
		//		If we do this, then BE SURE not to overwrite the values of _lf as
		//		it is used to match with a pcf in our Compare().
		//
		// get text metrics, in logical units, that are constant for this font,
		// regardless of the hdc in use.
		GetTextMetrics();

		HFONT hfontOld = SelectFont(_hdc, _hfont);
		GetTextFace(_hdc, LF_FACESIZE, szNewFaceName);
		SelectFont(_hdc, hfontOld);
	}

	return (_hfont != NULL);
}

/*
 *	BOOL CCcs::GetTextMetrics ( )
 *	
 *	@mfunc
 *		Get metrics used by the measurer and renderer.
 *
 *	@comm
 *		These are in logical coordinates which are dependent
 *		on the mapping mode and font selected into the hdc.
 */
BOOL CCcs::GetTextMetrics ()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::GetTextMetrics");

	BOOL		fRes = TRUE;
	HFONT		hfontOld;
	TEXTMETRIC	tm;

	AssertSz(_hfont, "No font has been created.");
	AssertSz(_hfont, "CCcs::Fill - CCcs has no font");

    if ( GetCurrentObject( _hdc, OBJ_FONT ) != _hfont )
    {
	    hfontOld = (HFONT)SelectObject(_hdc, _hfont);

        if(!hfontOld)
        {
 			fRes = FALSE;
        	DestroyFont();
            goto cleanup;
        }
    }
    else
        hfontOld = 0;

	if(!W32->GetTextMetrics(_hdc, &tm))
	{
		fRes = FALSE;
    	DestroyFont();
        goto cleanup;
	}

	// the metrics, in logical units, dependent on the map mode and font.
	_yHeight		= (SHORT) tm.tmHeight;
	_yDescent		= (SHORT) tm.tmDescent;
	_xAveCharWidth	= (SHORT) tm.tmAveCharWidth;
	_xOverhangAdjust= (SHORT) tm.tmOverhang;

	_xOverhang = 0;
	_xUnderhang	= 0;
	if ( _lf.lfItalic )
	{
		_xOverhang =  SHORT ( (tm.tmAscent + 1) >> 2 );
		_xUnderhang =  SHORT ( (tm.tmDescent + 1) >> 2 );
	}

	// if fix pitch, the tm bit is clear
	_fFixPitchFont = !(TMPF_FIXED_PITCH & tm.tmPitchAndFamily);
	_xDefDBCWidth = 0;

	_bCharSet = tm.tmCharSet;

	// If SYMBOL_CHARSET is used, use the A APIs with the low bytes of the
	// characters in the run
	if(_bCharSet == SYMBOL_CHARSET)
		_bConvertMode = CM_LOWBYTE;

	else if (_bConvertMode == CM_NONE)
	{
		_bConvertMode = W32->DetermineConvertMode( tm.tmCharSet );
	}

	CalcUnderlineInfo(&tm);

cleanup:

	if(hfontOld)
		SelectFont(_hdc, hfontOld);

	return fRes;
}

/*
 *	BOOL CCcs::CalcUnderlineInfo ( )
 *	
 *	@mfunc
 *		Calculate underline & strike out offsets
 *
 *	@rdesc
 *		None.
 */
void CCcs::CalcUnderlineInfo(
	TEXTMETRIC *ptm)		//@parm text metric for the font
{
	W32->CalcUnderlineInfo (this, ptm);
}


/* 	
 *	CCcs::DestroyFont
 *
 *	@mfunc
 *		Destroy font handle for this CCcs
 *
 */
VOID CCcs::DestroyFont()
{
	TRACEBEGIN(TRCSUBSYSFONT, TRCSCOPEINTERN, "CCcs::DestroyFont");

	// clear out any old font
	if(_hfont)
	{
		DeleteObject(_hfont);
		_hfont = 0;
	}
}

/*

⌨️ 快捷键说明

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