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

📄 rtfread2.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/*
 *	rtfread2.cpp
 *
 *	Description:
 *		This file contains the object functions for RichEdit RTF reader
 *
 *		Original RichEdit 1.0 RTF converter: Anthony Francisco
 *		Conversion to C++ and RichEdit 2.0:  Murray Sargent
 *
 *	* NOTE:
 *	*	All sz's in the RTF*.? files refer to a LPSTRs, not LPTSTRs, unless
 *	*	noted as a szW.
 *
 */

#include "_common.h"

#include "_rtfread.h"
#include "_coleobj.h"

const char szFontsel[]="\\f";

ASSERTDATA


/*
 *		CRTFRead::HandleFieldInstruction()
 *
 *		Purpose:
 *			Handle field instruction
 *
 *		Returns:
 *			EC					The error code
 */
EC CRTFRead::HandleFieldInstruction()
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::HandleFieldInstruction");

//TODO rewrite this function for common case
//FUTURE save field instruction

	BYTE *pch, *pch1;

	for(pch1 = _szText; *pch1 == ' '; pch1++)	// Bypass any leading blanks
		;
	for(pch = pch1; *pch && *pch != ' '; pch++)
		;

	_fHyperlinkField = FALSE;

	if(W32->ASCIICompareI(pch1, (BYTE *) "SYMBOL", 6))
		HandleFieldSymbolInstruction(pch);	//  SYMBOL

	else if (W32->ASCIICompareI(pch1, (BYTE *) "HYPERLINK", 9))
	{
		_fHyperlinkField = TRUE;
		HandleFieldHyperlink(pch);
	}
#ifdef PWD_JUPITER
	// GuyBark JupiterJ 49674: This field instruction is an Equation field!
	// These are used in FE RTF to specify Rubi text and the text beneath it.
	// I've seen the field results for such fields to be empty, which means 
	// that unless we take special action here, we'll lose the text completely.
	// So note that we're in an equation field.
	else if (W32->ASCIICompareI(pch1, (BYTE *) "eq", 2))
	{
	    LPSTR pOverstrikeStart = "\\o";

	    // We can only handle this group if it contains the overstrike group.
	    if(strstr((LPSTR)pch1, pOverstrikeStart))
	    {
	        _fEquationField = TRUE;

	        // Store the cp at the start of the equation field.
	        _cpFieldInstruction = _prg->GetCp();

	        // Set up the current text y offset from this equation string.
	        SetupEquationOffset((LPSTR)pch1);
	    }
	}
#endif // PWD_JUPITER

	// save the current formatting for the field result
	_FieldCF = _CF;
	_ptfField = _pstateStackTop->ptf;
	_nFieldCodePage = _pstateStackTop->nCodePage;


	TRACEERRSZSC("HandleFieldInstruction()", - _ecParseError);
	return _ecParseError;
}

/*
 *	HandleFieldSymbolInstruction(pch)
 *
 *	@mfunc
 *		Handle specific  symbol field
 *
 *	@rdesc
 *		EC	The error code
 *
 *	@devnote 
 *		FUTURE: the two whiles below can be combined into one fairly easily;
 *		Look at the definitions of IsXDigit() and IsDigit() and introduce
 *		a variable flag as well as a variable base multiplier (= 10 or 16).
 */
EC CRTFRead::HandleFieldSymbolInstruction(
	BYTE *pch )		//@parm Pointer to SYMBOL field instruction
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::HandleFieldInstruction");

	BYTE	ch;
	BYTE	chSymbol = 0;
	const char *pchFontsel = szFontsel;
	STATE *	pstate = _pstateStackTop;

	while (*pch == ' ')						// Eat spaces
		++pch;
											// Collect symbol char's code 
	if (*pch == '0' &&						//  which may be in decimal
 		(*++pch | ' ') == 'x')				//  or hex
	{										// It's in hex
		ch = *++pch;
	   	while (ch && ch != ' ')
	   	{
	   		if (IsXDigit(ch))
			{
				chSymbol <<= 4;
				chSymbol += (ch <= '9') ? ch - '0' : (ch & 0x4f) - 'A' + 10;
			}
			else
			{
			 	_ecParseError = ecUnexpectedChar;
				goto CleanUp;
			}
			ch = *pch++;
	   	}
	}
	else									// Decimal
	{
	   ch = *pch;
	   while (ch && ch != ' ')
	   {
	    	if (IsDigit(ch))
			{
				chSymbol *= 10;
				chSymbol += ch - '0' ;
			}
			else
			{
			 	_ecParseError = ecUnexpectedChar;
				goto CleanUp;
			}
			ch = *++pch;
	   }
	}
	_szSymbolFieldResult = (BYTE *)PvAlloc(2, GMEM_ZEROINIT);
    if (NULL != _szSymbolFieldResult)
    {
	    _szSymbolFieldResult[0] = chSymbol;
    }    
    else
    {
        Assert(_szSymbolFieldResult);  //give us a chance to debug
    }
    

	// now check for the \\f "Facename" construct 
	// and deal with it

	while (*pch == ' ')						// Eat spaces
	{
		++pch;
	}

	while (*pch && *pch == *pchFontsel)		// Make sure *pch is a \f
	{										
		++pch;
		++pchFontsel;
	}
	if	(! (*pchFontsel) )
	{
		_ecParseError = HandleFieldSymbolFont(pch);	//  \\f "Facename"
	}

// ASSERTION   font & font size  will be in field result \flds
// BUGBUG: A more robust implementation would parse the font
// and font size from both \fldinst and \fldrslt (RE1.0 does this)
	
CleanUp:
	TRACEERRSZSC("HandleFieldInstruction()", - _ecParseError);
	return _ecParseError;
}

/*
 *	HandleFieldSymbolFont()
 *
 *	@mfunc
 *		Handle the \\f "Facename" instruction in the SYMBOL field
 *
 *	@rdesc
 *		EC	The error code
 *
 *	@devnote WARNING: may change _szText
 */
EC CRTFRead::HandleFieldSymbolFont(BYTE *pch)
{
	SHORT iFont = _fonts.Count();
	TEXTFONT tf;
	TEXTFONT *ptf = &tf;

	_pstateStackTop->ptf = &tf;
	// ReadFontName tries to append
	tf.szName[0] = '\0';

	// skip the initial blanks and quotes
	while (*pch && (*pch == ' ' || *pch == '\"'))
	{
		++pch;
	}

	// DONT WORRY, we'll get it back to normal
	// ReadFontName depends on _szText, so we need to alter it and then restore
	// it's just too bad we have to do it ...
	BYTE* szTextBAK = _szText;
	BOOL fAllAscii = TRUE;

	_szText = pch;

	// transform the trailing quote into ';'
	while (*pch)
	{
		if (*pch == '\"')
		{
			*pch = ';';
			break;
		}

		if(*pch > 0x7f)
		{
			fAllAscii = FALSE;
		}
		++pch;
	}

	// NOW we can read the font name!!
	ReadFontName(_pstateStackTop, fAllAscii ? ALL_ASCII : CONTAINS_NONASCII);

	// Try to find this face name in the font table
	BOOL fFontFound = FALSE;
	for (SHORT i = 0; i < iFont; ++i)
	{
		TEXTFONT *ptfTab = _fonts.Elem(i);
		if (0 == wcscmp(ptf->szName, ptfTab->szName))
		{
			fFontFound = TRUE;
			i = ptfTab->sHandle;
			break;
		}
	}

	// did we find the face name?
	if (!fFontFound)
	{
		Assert(i == iFont);
		i+= RESERVED_FONT_HANDLES;

		// Make room in font table for
		//  font to be inserted
		if (!(ptf =_fonts.Add(1,NULL)))
		{									
			_ped->GetCallMgr()->SetOutOfMemory();
			_ecParseError = ecNoMemory;
			goto exit;
		}

		// repeating inits from tokenFontSelect
		ptf->sHandle	= i;				// Save handle
		wcscpy(ptf->szName, tf.szName); 
		ptf->bPitchAndFamily = 0;
		ptf->fNameIsDBCS = FALSE;
		ptf->sCodePage = _nCodePage;
		ptf->bCharSet = DEFAULT_CHARSET;	// SYMBOL_CHARSET ??
	}

	SelectCurrentFont(i);
	
exit:
	// needs to go back to normal
	_szText = szTextBAK;

	return _ecParseError;
}

/*
 *	HandleFieldHyperlink(pch)
 *
 *	@mfunc
 *		Handle HYPERLINK field
 *
 *	@rdesc
 *		EC	The error code
 */
EC CRTFRead::HandleFieldHyperlink(
	BYTE *pch )		//@parm Pointer to HYPERLINK field instruction
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::HandleFieldHyperlink");

	BYTE *pBuffer;

	if ( *pch )
	{
		for( ; *pch == ' '; pch++) ;				// Skip leading blanks
	}

	// allocate the buffer and add the string to it
	_cchHyperlinkFldinst = MAX_PATH;
	_cchHyperlinkFldinstUsed = 1;
	pBuffer = (BYTE *)PvAlloc( MAX_PATH, GMEM_FIXED );
	
	if ( !pBuffer )
	{
		return ( _ecParseError = ecNoMemory );		 
	}

	pBuffer[0] = ' ';
	pBuffer[1] = '\0';
	_szHyperlinkFldinst = pBuffer;
	
	if ( *pch )
	{	
		_ecParseError = AppendString( &_szHyperlinkFldinst, pch, &_cchHyperlinkFldinst, &_cchHyperlinkFldinstUsed );
	}

	return _ecParseError;
}

/*
 *		CRTFRead::ReadData(pbBuffer, cbBuffer)
 *
 *		Purpose:
 *			Read in object data. This must be called only after all initial
 *			object header info has been read.
 *
 *		Arguments:
 *			pbBuffer		pointer to buffer where to put data
 *			cbBuffer		how many bytes to read in
 *
 *		Returns:
 *			LONG			number of bytes read in
 *
 */
LONG CRTFRead::ReadData(BYTE * pbBuffer, LONG cbBuffer)
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::ReadData");

	LONG cbLeft = cbBuffer;

	BYTE bChar0;
	BYTE bChar1;

	while (cbLeft && (bChar0 = GetHexSkipCRLF()) < 16 && 
						(bChar1 = GetHexSkipCRLF()) < 16)
	{	
		*pbBuffer++ = bChar0 << 4 | bChar1;
		cbLeft--;
	}							   

	return cbBuffer - cbLeft ; 
}

/*
 *		CRTFRead::ReadBinaryData(pbBuffer, cbBuffer)
 *
 *		Purpose:
 *
 *		Arguments:
 *			pbBuffer		pointer to buffer where to put data
 *			cbBuffer		how many bytes to read in
 *
 *		Returns:
 *			LONG			number of bytes read in
 */
LONG CRTFRead::ReadBinaryData(BYTE *pbBuffer, LONG cbBuffer)
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::ReadBinaryData");

	LONG cbLeft = min(_cbBinLeft, cbBuffer);

	cbBuffer = cbLeft;

	for (; cbLeft >0 ; cbLeft--)
	{
		*pbBuffer++ = GetChar();
	}

	_cbBinLeft -= cbBuffer; 

	return cbBuffer ;
}

/*
 *		CRTFRead::SkipBinaryData(cbBuffer)
 *
 *		Purpose:
 *
 *		Arguments:
 *			cbBuffer		how many bytes to skip
 *
 *		Returns:
 *			LONG			number of bytes skipped
 */
LONG CRTFRead::SkipBinaryData(LONG cbSkip)
{
	BYTE rgb[1024];

	_cbBinLeft = cbSkip;

	while(ReadBinaryData(rgb, sizeof(rgb)) > 0) 
	{
	}

	return cbSkip;
}

/*
 *		CRTFRead::StrAlloc(ppsz, sz)
 *
 *		Purpose:
 *			Set up a pointer to a newly allocated space to hold a string
 *
 *		Arguments:
 *			ppsz			Ptr to ptr to string that needs allocation
 *			sz				String to be copied into allocated space
 *
 *		Returns:
 *			EC				The error code
 */
EC CRTFRead::StrAlloc(TCHAR ** ppsz, BYTE * sz)
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::StrAlloc");

	int Length =  strlen((CHAR *)sz)+1 ;

	*ppsz = (TCHAR *) PvAlloc((Length + 1)*sizeof(TCHAR), GMEM_ZEROINIT);
	if (!*ppsz)
	{
		_ped->GetCallMgr()->SetOutOfMemory();
		_ecParseError = ecNoMemory;
		goto Quit;
	}
	
	MultiByteToWideChar(CP_ACP,0,(char *)sz,-1,*ppsz,Length) ;

Quit:
	return _ecParseError;
}

/*
 *		CRTFRead::FreeRtfObject()
 *
 *		Purpose:
 *			Cleans up memory used by prtfobject
 */
void CRTFRead::FreeRtfObject()
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "CRTFRead::FreeRtfObject");

	if (_prtfObject)
	{
		FreePv(_prtfObject->szClass);
		FreePv(_prtfObject->szName);
		FreePv(_prtfObject);
		_prtfObject = NULL;
	}
}

/*
 *	CRTFRead::ObjectReadSiteFlags
 *
 *	Purpose:
 *		Read the dwFlags and dwUser bytes from a container specific stream
 *
 *	Arguments:
 *		preobj			The REOBJ from where to copy the flags this preobj is
 *						then later put out in a site
 *
 *	Returns:
 *		BOOL			TRUE if successfully read the bytes
 */
BOOL CRTFRead::ObjectReadSiteFlags( REOBJECT * preobj)
{
	return (::ObjectReadSiteFlags(preobj) == NOERROR);
}

/*
 *	ObjectReadFromStream
 *
 *	Purpose:
 *		Reads an OLE object from the RTF output stream.
 *
 *
 *	Returns:
 *		BOOL		TRUE on success, FALSE on failure.
 */
BOOL CRTFRead::ObjectReadFromEditStream(void)
{
	HRESULT hr;
	BOOL fRet = FALSE;
	REOBJECT reobj = { 0 };
	LPRICHEDITOLECALLBACK  precall=NULL;
	WCHAR 	ch = WCH_EMBEDDING;
	LPOLECACHE polecache = NULL;
	LPENUMSTATDATA penumstatdata = NULL;
	STATDATA statdata;
	BOOL fGotClsid = TRUE;

	CObjectMgr *ObjectMgr = _ped->GetObjectMgr();

	if (! ObjectMgr)
	   goto Cleanup;
	
	precall = ObjectMgr->GetRECallback();

	// If no IRichEditOleCallback exists, then fail
	if (!precall)
		goto Cleanup;

//	AssertSz(_prtfObject->szClass,"ObFReadFromEditstream: reading unknown class");

	//$ REVIEW: MAC This call is incorrect for the Mac.  It may not matter though

	//          if ole support in RichEdit is not needed for the Mac.
	if (!(_prtfObject->szClass && 
		pCLSIDFromProgID(_prtfObject->szClass, &reobj.clsid)
		== NOERROR))
	{
		fGotClsid = FALSE;
	}

	// Get storage for the object from the application
	if (FAILED(precall->GetNewStorage(&reobj.pstg)))
	{
		goto Cleanup;
	}

	hr = pOleConvertOLESTREAMToIStorage((LPOLESTREAM) &RTFReadOLEStream, reobj.pstg, NULL);
	if (FAILED(hr))					   
		goto Cleanup;		  

⌨️ 快捷键说明

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