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

📄 rtfread.cpp

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

	// Adjust the PF for the new _pstateStackTop and delete unused PF's.
	if(pstate->sDest == destParaNumbering || pstate->sDest == destParaNumText)
	{
		if(pstatePrev && pstate->pPF != pstatePrev->pPF)
		{
			// Bleed the PF of the current state into the previous state for
			// paragraph numbering groups
			Assert(pstatePrev->pPF);
			pstatePrev->DeletePF();
			pstatePrev->pPF = pstate->pPF;
			pstate->pPF = NULL;
		}
		else
			pstate->DeletePF();
		// N.B.  Here, we retain the _PF diffs since they apply to the
		//	enclosing group along with the PF of the group we are leaving
	}
	else
	{
		// We're popping the state, so delete its PF and discard the _PF diffs
		Assert(pstate->pPF);
		pstate->DeletePF();

		// If !pstatePrev, we're ending the parse, in which case the _PF
		//	structure contains final PF (so don't toast it).
		if(pstatePrev)
		{
			_PF.dwMask = 0;
		}
	}

	if(pstatePrev)
	{
		_CF.dwMask = 0;							// Discard any CF deltas

		switch(pstate->sDest)
		{
			case destParaNumbering:
				// {\pn ...}
				pstatePrev->sIndentNumbering = pstate->sIndentNumbering;
				pstatePrev->fBullet = pstate->fBullet;
				break;

			case destObject:
				// clear our object flags just in case we have corrupt RTF
				if(_fNeedPres)
				{
					_fNeedPres = FALSE;
					_fNeedIcon = FALSE;
					_pobj = NULL;
				}
				break;

			case destFontTable:
				if(pstatePrev->sDest == destFontTable)
				{
					// We're actually leaving a sub-group within the \fonttbl
					// group.
					break;
				}

				// We're leaving the {\fonttbl...} group.

#ifdef DEBUG
				_fSeenFontTable = TRUE;
#endif

				// Default font should now be defined, so select it
				//  (this creates CF deltas)
				SetPlain(pstate);

				// Ensure that a document-level codepage has been determined and
				// then scan the font names and retry the conversion to Unicode,
				// if necessary.

				if(_nCodePage == INVALID_CODEPAGE)
				{
					// We haven't determined a document-level codepage
					// from the \ansicpgN tag, nor from the font table
					// \fcharsetN and \cpgN values.  As a last resort,
					// let's use the \deflangN and \deflangfeN tags

					LANGID langid;

					if(_sDefaultLanguageFE != INVALID_LANGUAGE)
					{
						langid = _sDefaultLanguageFE;
					}
					else if(_sDefaultLanguage != INVALID_LANGUAGE &&
								_sDefaultLanguage != sLanguageEnglishUS)
					{
						// _sDefaultLanguage == sLanguageEnglishUS is inreliable
						// in the absence of \deflangfeN.  Many FE RTF writers
						// write \deflang1033 (sLanguageEnglishUS).

						langid = _sDefaultLanguage;
					}
					else 
					{
						goto NoLanguageInfo;
					}

					_nCodePage = ConvertLanguageIDtoCodePage(langid);
				}

NoLanguageInfo:
				if(_nCodePage == INVALID_CODEPAGE)
				{
					break;
				}

				// Fixup mis-converted font face names

				TEXTFONT *ptf;
				UINT i;

				for(i = 0; i < _fonts.Count(); i++)
				{
					ptf = _fonts.Elem(i);

					if(ptf->sCodePage == INVALID_CODEPAGE ||
						ptf->sCodePage == SYMBOL_CODEPAGE)
					{
						if(ptf->fNameIsDBCS)
						{
							char szaTemp[LF_FACESIZE];
							BOOL fMissingCodePage;

							// un-convert mis-converted face name
							SideAssert(WCTMB(ptf->sCodePage, 0, 
												ptf->szName, -1,
												szaTemp, sizeof(szaTemp),
												NULL, NULL, &fMissingCodePage) > 0);
							Assert(ptf->sCodePage == SYMBOL_CODEPAGE || 
										fMissingCodePage);

							// re-convert face name using new codepage info
							SideAssert(MBTWC(_nCodePage, 0,
										szaTemp, -1,
										ptf->szName, sizeof(ptf->szName) / sizeof(ptf->szName[0]),
										&fMissingCodePage) > 0);

							if(!fMissingCodePage)
							{
								ptf->fNameIsDBCS = FALSE;
							}
						}
					}
				}
				break;

			default:;
				// nothing
		}

		_prg->Set_iCF(pstatePrev->iCF);			// Restore previous CharFormat
		ReleaseFormats(pstatePrev->iCF, -1);
	}

done:
	TRACEERRSZSC("HandleEndGroup()", - _ecParseError);
	return _ecParseError;
}

/*
 *	CRTFRead::SelectCurrentFont(iFont)
 *
 *	@mfunc
 *		Set active font to that with index <p iFont>. Take into account
 *		bad font numbers.
 */
void CRTFRead::SelectCurrentFont(
	INT iFont)					// @parm font handle of font to select
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::SelectCurrentFont");

	LONG		i		= _fonts.Count();
	STATE *		pstate	= _pstateStackTop;
	TEXTFONT *	ptf		= _fonts.Elem(0);

	AssertSz(i,	"CRTFRead::SelectCurrentFont: bad font collection");

    if (NULL == pstate)
    {
	    AssertSz(pstate, "CRTFRead::SelectCurrentFont: bad state pointer");
	    return;
    }
    

	
	for(; i-- && iFont != ptf->sHandle; ptf++)	// Search for font with handle
		;										//  iFont

	// Font handle not found: use default, which is valid
	//  since \rtf copied _prg's
	if(i < 0)									
		ptf = _fonts.Elem(0);
												
	BOOL fDefFontFromSystem = (i == (LONG)_fonts.Count() - 1 || i < 0) &&
								!_fReadDefFont;

	StringCchCopy(_CF.szFaceName, sizeof(_CF.szFaceName) / sizeof(_CF.szFaceName[0]), ptf->szName);
	_CF.bInternalMask	 |=  CFMI_FACENAMEISDBCS;
	_CF.bInternalEffects &= ~CFEI_FACENAMEISDBCS;
	if( ptf->fNameIsDBCS )
		_CF.bInternalEffects |= CFEI_FACENAMEISDBCS;

	if(pstate->sDest != destFontTable)
	{
		_CF.bCharSet		= ptf->bCharSet;
		_CF.bPitchAndFamily	= ptf->bPitchAndFamily;
		_CF.dwMask			|= CFM_FACE | CFM_CHARSET;
	}

	// Ensure that the state's codepage is not supplied by the system.
	// That is, if we are using the codepage info from the default font,
	// be sure that the default font info was read from the RTF file.
	pstate->SetCodePage(((fDefFontFromSystem || ptf->sCodePage == INVALID_CODEPAGE) 
						? _nCodePage : ptf->sCodePage));

	pstate->ptf = ptf;

#ifdef CHICAGO
	// Win95c 1719: try to match a language to the char set when RTF
	// 				doesn't explicitly set a language

	if (!pstate->fExplicitLang && ptf->bCharSet != ANSI_CHARSET &&
		(!pstate->sLanguage || pstate->sLanguage == sLanguageEnglishUS))
	{
		i = AttIkliFromCharset(_ped, ptf->bCharSet);
		if (i >= 0)
			pstate->sLanguage = LOWORD(rgkli[i].hkl);
	}
#endif	// CHICAGO
}

/*
 *	CRTFRead::SetPlain()
 *
 *	@mfunc
 *		Setup _CF for \plain
 */
void CRTFRead::SetPlain(STATE *pstate)
{
	ZeroMemory(&_CF, _CF.cbSize);
	_CF.cbSize		= sizeof(CHARFORMAT2);
	_CF.dwMask		= CFM_ALL2;
	_CF.dwEffects	= CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; // Set default effects
	_CF.yHeight		= PointsToFontHeight(yDefaultFontSize);
	if(_sDefaultLanguage == INVALID_LANGUAGE)
	{
		_CF.dwMask &= ~CFM_LCID;
	}
	else
	{
		_CF.lcid = MAKELCID((WORD)_sDefaultLanguage, SORT_DEFAULT);
	}
	_CF.bUnderlineType = CFU_UNDERLINE;
	SelectCurrentFont(_sDefaultFont);

	// TODO: get rid of pstate->sLanguage, since CHARFORMAT2 has lcid
	pstate->sLanguage	  = _sDefaultLanguage;
	pstate->fExplicitLang = FALSE;

#ifdef BIDI
	// Character inherits para's direction
	//$ REVIEW: What happens on \rtlpar\ltrch\plain ? Is this even legal ?
	FlushDirection();
	pstate->fRightToLeft = pstate->fRightToLeftPara;
#endif
}

/*
 *	CRTFRead::ReadFontName(pstate)
 *
 *	@mfunc
 *		read font name _szText into <p pstate>->ptf->szName and deal with
 *		tagged fonts
 */
void CRTFRead::ReadFontName(
	STATE *	pstate,			// @parm state whose font name is to be read into
	int iAllASCII)			// @parm indicates that _szText is all ASCII chars
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::ReadFontName");

	if (pstate->ptf)
	{
		INT		cchName = LF_FACESIZE - 1;
		TCHAR *	pchDst = pstate->ptf->szName;
		char  * pachName =  (char *)_szText ;
        
		// Append additional text from _szText to TEXTFONT::szName

		// We need to append here since some RTF writers decide
		// to break up a font name with other RTF groups
		while(*pchDst && cchName > 0)
		{
			pchDst++;
			cchName--;
		}

		INT cchLimit = cchName;
		while (*pachName &&
			   *pachName != ';' &&
			   cchLimit)		// Remove semicolons
		{
			pachName++;
			cchLimit--;
		}
		*pachName = '\0';

#ifdef PWD_JUPITER
        // GuyBark:
        // The Office converters can output font decorations to the font names. PWord does
        // not want these decorations, as the fonts on the device are capable of displaying
        // characters from multiple character sets. So strip the decorations from the font
        // names if there are any. Note: this is not the same action as RichEdit does later
        // with the font substitution, that looks in the .ini files for replacing some 
        // fonts with other fonts.

        // We don't need to do this if the font's charset is plain ol' Western ANSI.
        if(pstate->ptf->bCharSet)
        {
            int i = 0, cchFont, cchDecoration;

            // Get the length of the incoming font name. All font names here are MBCS.
            cchFont = strlen((LPSTR)_szText);

            // For all the decorations we can expect...
            while(fontDec[i].pszName)
            {
                // Get the length of this decoration. Assume that the decoration is always preceded 
                // by a space. This reduces the chance of doing something the user doesn't expect.

                cchDecoration = strlen(fontDec[i].pszName);

                // If this charset of the incoming font and the decoration match, 
                // check for the decoration in the font name.

                if((pstate->ptf->bCharSet == fontDec[i].charset) &&
                   (cchFont > cchDecoration) &&
                   !strcmp((LPSTR)&_szText[cchFont - cchDecoration], fontDec[i].pszName))
                {
                    // It has the decoration! So chop it off.
                    _szText[cchFont - cchDecoration] = '\0';

                    break;
                }

                // Oh well, try the next font decoration.
                ++i;
            }
        }
#endif // PWD_JUPITER

		// Use the codepage of the font in all cases except where the font uses
		// the symbol charset (and the codepage has been mapped from the charset)
		// and UTF-8 isn't being used
		LONG nCodePage = pstate->nCodePage != SYMBOL_CODEPAGE 
						? pstate->nCodePage : _nCodePage;

		BOOL fMissingCodePage;
		Assert(!(_dwFlags & SFF_UTF8) || nCodePage == CP_UTF8);
		INT cch = MBTWC(nCodePage, 0, 
						(char *)_szText, -1, 
						pchDst, cchName, &fMissingCodePage);

		if(cch > 0 && fMissingCodePage && iAllASCII == CONTAINS_NONASCII)
			pstate->ptf->fNameIsDBCS = TRUE;

		// Make sure destination is null terminated
		if(cch > 0)
			pchDst[cch] = 0;

		// Fall through even if MBTWC <= 0, since we may be appending text to an
		// existing font name.

		if (pstate->ptf == _fonts.Elem(0))		// If it's the default font,
			SelectCurrentFont(_sDefaultFont);	//  update _CF accordingly

		TCHAR *	szNormalName;

		if (pstate->ptf->bCharSet && pstate->fRealFontName)
		{
			// if we don't know about this font don't use the real name
			if (!FindTaggedFont(pstate->ptf->szName,
							pstate->ptf->bCharSet, &szNormalName))
			{
				pstate->fRealFontName = FALSE;
				pstate->ptf->szName[0] = 0;
			}
		}
		else if (IsTaggedFont(pstate->ptf->szName,
							&pstate->ptf->bCharSet, &szNormalName))
		{
			wcscpy(pstate->ptf->szName, szNormalName);
			pstate->ptf->sCodePage = GetCodePage(pstate->ptf->bCharSet);
			pstate->SetCodePage(pstate->ptf->sCodePage);
		}
	}
}

/*
 *	CRTFRead::GetColor (dwMask)
 *
 *	@mfunc
 *		Store the autocolor or autobackcolor effect bit and return the
 *		COLORREF for color _iParam
 *
 *	@rdesc
 *		COLORREF for color _iParam
 *
 *	@devnote
 *		If the entry in _colors corresponds to tomAutoColor, gets the value
 *		RGB(0,0,0) (since no \red, \green, and \blue fields are used), but
 *		isn't used by the RichEdit engine.  Entry 1 corresponds to the first
 *		explicit entry in the \colortbl and is usually RGB(0,0,0). The _colors
 *		table is built by HandleToken() when it handles the token tokenText
 *		for text consisting of a ';' for a destination destColorTable.
 */
COLORREF CRTFRead::GetColor(
	DWORD dwMask)		//@parm Color mask bit
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::GetColor");

	if((DWORD)_iParam >= _colors.Count())		// Illegal _iParam
		return RGB(0,0,0);

	_CF.dwMask	  |= dwMask;					// Turn on appropriate mask bit
	_CF.dwEffects &= ~dwMask;					// auto(back)color off: color is to be used

	COLORREF Color = *_colors.Elem(_iParam);
	if(Color == tomAutoColor)
	{
		_CF.dwEffects |= dwMask;				// auto(back)color on				
		Color = RGB(0,0,0);
	}		
	return Color;
}

/*
 *	CRTFRead::GetStandardColorIndex ()
 *
 *	@mfunc
 *		Return the color index into the standard 16-entry Word \colortbl
 *		corresponding to the color index _iParam for the current \colortbl
 *

⌨️ 快捷键说明

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