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

📄 rtfwrit.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 *	CRTFWrite::printF(szFmt, ...)
 *
 *	@mfunc
 *		Provide formatted output
 *
 *	@rdesc
 *		TRUE if successful
 */
BOOL _cdecl CRTFWrite::printF(
	CONST CHAR * szFmt,		// @parm Format string for printf()
	...)					// @parmvar Parameter list
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::printF");
	va_list	marker;

    const INT c_chT = 60;
    
	CHAR	szT[c_chT];
	int cb;
	va_start(marker, szFmt);
	cb = W32->WvsprintfA(c_chT, szT, szFmt, marker);
	va_end(marker);

    // Truncate if needed
    cb = min(cb, c_chT);
    
	return Puts(szT, cb);
}

/*
 *	CRTFWrite::sprintF(szBuf, szFmt, ...)
 *
 *	@mfunc
 *		Provide formatted output to a string buffer
 *
 *	@rdesc
 *		number of bytes written
 */
LONG _cdecl CRTFWrite::sprintF(
	LONG cbBuf,
	CHAR *szBuf,
	CONST CHAR * szFmt,		// @parm Format string for printf()
	...)					// @parmvar Parameter list
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::printF");
	va_list	marker;
	int cb;
	va_start(marker, szFmt);
	cb = W32->WvsprintfA(cbBuf, szBuf, szFmt, marker);
	va_end(marker);
	return cb;
}
/*
 *	CRTFWrite::WritePcData(szData, nCodePage, fIsDBCS)
 *
 *	@mfunc
 *		Write out the string <p szData> as #PCDATA where any special chars
 *		are protected by leading '\\'.
 *
 *	@rdesc
 *		EC (_ecParseError)
 */
EC CRTFWrite::WritePcData(
	const TCHAR * szData,	// @parm #PCDATA string to write
	INT  nCodePage,			// @parm code page  default value CP_ACP
	BOOL fIsDBCS)			// @parm szData is a DBCS string stuffed into Unicode buffer
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WritePcData");

	BYTE		ch;
	BOOL		fMissingCodePage;
	BOOL		fMultiByte;
	const BYTE *pch;
	const char *pchToDBCSDefault = NULL;
	BOOL *		pfUsedDefault = NULL;

	if(_dwFlags & SFF_UTF8)				// Use UTF-8 for all conversions
		nCodePage = CP_UTF8;			// (doesn't work for unknown cpg's
										//  i.e., if fIsDBCS is TRUE...)
	if(!*szData)
	{
		return _ecParseError;
	}

	int	DataSize = wcslen(szData) + 1;
	int BufferSize = DataSize * 2;

#ifdef PWD_JUPITER
	// GuyBark JupiterJ 51164:
	// Yes, well, "* 2" may be ok for Unicode to DBCS. but it's too small to
	// cope with conversion to UTF8. So bump it up to always be big enough.
	BufferSize *= 3;
#endif // PWD_JUPITER

	char *pBuffer = (char *)PvAlloc(BufferSize * 2, GMEM_ZEROINIT);
	if(!pBuffer)
	{
		return ecNoMemory;
	}

#ifdef DEBUG
	// When WCTMB fails to convert a char, the following default
	// char is used as a placeholder in the string being converted
	const char	chToDBCSDefault = 0;
	BOOL		fUsedDefault;

	pchToDBCSDefault = &chToDBCSDefault;
	pfUsedDefault	 = &fUsedDefault;
#endif

	int cchRet = WCTMB(fIsDBCS ? INVALID_CODEPAGE : nCodePage, 0, 
						szData, -1, pBuffer, BufferSize,
						pchToDBCSDefault, pfUsedDefault,
						&fMissingCodePage);
	Assert(cchRet > 0);

	if(!fIsDBCS && fMissingCodePage && nCodePage != CP_ACP)
	{
		// Here, the system could not convert the Unicode string because the
		// code page is not installed on the system.  Fallback to CP_ACP.

		cchRet = WCTMB(CP_ACP, 0, 
						szData, -1, pBuffer, BufferSize,
						pchToDBCSDefault, pfUsedDefault,
						&fMissingCodePage);
		Assert(cchRet > 0);

		nCodePage = CP_ACP;
	}

	AssertSz(!fUsedDefault, "CRTFWrite::WritePcData():  Found character in "
							"control text which cannot be converted from "
							"Unicode");
	if(cchRet <= 0)
	{
		_ecParseError = ecCantUnicode;
		goto CleanUp;
	}

	BufferSize = cchRet;

	fMultiByte = (BufferSize > DataSize) || fIsDBCS || fMissingCodePage;
	pch = (BYTE *)pBuffer;
	ch = *pch;
	
	// If _fNeedDelimeter, may need	to PutChar(' ')
	CheckDelimeter();
									
	while (!_ecParseError && (ch = *pch++))
	{
		if(fMultiByte && *pch && IsLeadByte(ch, nCodePage))
		{
			printF(szEscape2CharFmt, ch, *pch++);
		}
		else
		{
			if(ch == LBRACE || ch == RBRACE || ch == BSLASH)
			{
				printF(szLiteralCharFmt, ch);
			}
			else if(ch < 32 || ch == ';' || ch > 127)
			{
				printF(szEscapeCharFmt, ch);
			}
			else
			{
				PutChar(ch);
			}
		}
	}

CleanUp:
	FreePv(pBuffer); 
	return _ecParseError;
}

/*
 *	CRTFWrite::LookupColor(colorref)
 *
 *	@mfunc
 *		Return color-table index for color referred to by <p colorref>.
 *		If a match isn't found, an entry is added.
 *
 *	@rdesc
 *		LONG			Index into colortable
 *		<lt> 0			on error
 */
LONG CRTFWrite::LookupColor(
	COLORREF colorref)		// @parm colorref to look for
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::LookupColor");

	LONG		Count = _colors.Count();
	LONG		iclrf;
	COLORREF *	pclrf;

	for(iclrf = 0; iclrf < Count; iclrf++)		// Look for color
		if(_colors.GetAt(iclrf) == colorref)
		 	return iclrf;

	pclrf = _colors.Add(1, NULL);				// If we couldn't find it,
	if(!pclrf)									//  add it to color table
		return -1;
	*pclrf = colorref;

	return iclrf;
}

/*
 *	CRTFWrite::LookupFont(pCF)
 *
 *	@mfunc
 *		Returns index into font table for font referred to by
 *		CCharFormat *<p pCF>. If a match isn't found, an entry is added.
 *
 *	@rdesc
 *		SHORT		Index into fonttable
 *		<lt> 0		on error
 */
LONG CRTFWrite::LookupFont(
	CCharFormat const * pCF)	// @parm CCharFormat holding font name
{								//		 to look up
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::LookupFont");

	LONG		Count = _fonts.Count();
	LONG		itf;
	TEXTFONT *	ptf;
	
	for(itf = 0; itf < Count; itf++)
	{														// Look for font
		ptf = _fonts.Elem(itf);
		if (ptf->bPitchAndFamily == pCF->bPitchAndFamily &&	//  of same pitch,
			ptf->bCharSet		 == pCF->bCharSet &&		//  char set, and
			!wcscmp(ptf->szName, pCF->szFaceName))			//  name
		{
			return itf;										// Found it
		}
	}
	ptf = _fonts.Add(1, NULL);								// Didn't find it:
	if(!ptf)												//  add to table
		return -1;

	ptf->bPitchAndFamily = pCF->bPitchAndFamily;
	ptf->bCharSet		 = pCF->bCharSet;
	ptf->sCodePage		 = GetCodePage (ptf->bCharSet);
	wcscpy(ptf->szName, pCF->szFaceName);
	ptf->fNameIsDBCS = (pCF->bInternalEffects & CFEI_FACENAMEISDBCS);

#if 0
	// Bug1523 - (BradO) I removed this section of code so that a /fN tag is always
	// emitted for the first run of text.  In theory, we should be able to
	// assume that the first run of text would carry the default font.
	// It turns out that when reading RTF, Word doesn't use anything predictable
	// for the font of the first run of text in the absence of an explicit /fN, 
	// thus, we have to explicitly emit a /fN tag for the first run of text.
	if(!Count)												// 0th font is
	{														//  default \deff0
		_CF.bPitchAndFamily	= pCF->bPitchAndFamily;			// Set "previous"
		_CF.bCharSet		= pCF->bCharSet;				//  CF accordingly
		wcscpy(_CF.szFaceName, pCF->szFaceName);
	}
#endif

	return itf;
}

/*
 *	CRTFWrite::BuildTables(prp, cch)
 *
 *	@mfunc
 *		Build font and color tables for write range of length <p cch> and
 *		charformat run ptr <p prp>
 *
 *	@rdesc
 *		EC			The error code
 */
EC CRTFWrite::BuildTables(
	CFormatRunPtr& rpCF,	// @parm CF run ptr for start of write range
	CFormatRunPtr& rpPF,	// @parm PF run ptr for start of write range
	LONG cch)				// @parm # chars in write range
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::BuildTables");

	LONG				i;
	LONG				ifmt = 0;
	const CCharFormat *	pCF = NULL;
	const CParaFormat * pPF = NULL;
	CFormatRunPtr		rp(rpCF);
	CFormatRunPtr		rpPFtemp(rpPF);
	LONG				cchTotal = cch;

	while(cch > 0)
	{
		ifmt = rp.GetFormat();					// _iFormat for next CF run
		pCF = _ped->GetCharFormat(ifmt);

		if( !pCF )
			goto CacheError;

		// Look up character-format *pCF's font and color. If either isn't
		// found, it is added to appropriate table.  Don't lookup color
		// for CCharFormats with auto-color

		if (LookupFont(pCF) < 0 ||
			(!(pCF->dwEffects & CFE_AUTOCOLOR) &&
				LookupColor(pCF->crTextColor) < 0) ||
			(!(pCF->dwEffects & CFE_AUTOBACKCOLOR) &&
				LookupColor(pCF->crBackColor) < 0))
		{
			break;
		}
		if(!rp.IsValid())
			break;
		cch -= rp.GetCchLeft();
		rp.NextRun();
	}

	// now look for bullets; if found, then we need to include
	// the "Symbol" font

	cch = cchTotal;
	_symbolFont = 0;

	while( cch > 0 )
	{
		ifmt = rpPFtemp.GetFormat();
		pPF = _ped->GetParaFormat(ifmt);

		if( !pPF )
		{
			goto CacheError;
		}
		
		if( pPF->wNumbering == PFN_BULLET )
		{
			// Save the Font index for Symbol.
			// Reset it to 0 if LookupFont return error.
			if ( (_symbolFont = LookupFont((CCharFormat *)&cfBullet)) < 0 )
				_symbolFont = 0;

			// We don't need to bother looking for more bullets, since
			// in RichEdit 2.0, all bullets either have the same font or
			// have their formatting information in the character format
			// for the EOP mark.

            // GuyBark: That may be true, but we still need to keep looping 
            // through the paragraghs for things like the stylesheet below.
//            break;
		}
		
		WORD  Widths = pPF->wBorderWidth;
		DWORD Colors = pPF->dwBorderColor & 0xFFFFF;

		while(Widths && Colors)
		{
			i = Colors & 0x1F;
			if(i && (Widths & 0xF))
				LookupColor(g_Colors[i - 1]);

			Widths >>= 4;
			Colors >>= 5;
		}
		
		i = (pPF->wShadingStyle >> 6) & 31;			// Shading forecolor
		if(i)
			LookupColor(g_Colors[i - 1]);
		i = pPF->wShadingStyle >> 11;				// Shading backcolor
		if(i)
			LookupColor(g_Colors[i - 1]);

		if(IsHeadingStyle(pPF->sStyle) && pPF->sStyle < _nHeadingStyle)
			_nHeadingStyle = pPF->sStyle;

		if(!rpPFtemp.IsValid())
			break;
		
		cch -= rpPFtemp.GetCchLeft();
		rpPFtemp.NextRun();
	}	

	return _ecParseError;

CacheError:
	_ecParseError = ecFormatCache;
	return ecFormatCache;					// Access to CF/PF cache failed
}

/*
 *	CRTFWrite::WriteFontTable()
 *
 *	@mfunc
 *		Write out font table
 *
 *	@rdesc
 *		EC				The error code
 */
EC CRTFWrite::WriteFontTable()
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteFontTable");

	LONG			Count = _fonts.Count();
	int				itf;
	int				m;
	int				pitch;
	TEXTFONT *ptf;
	char *			szFamily;
	TCHAR *			szTaggedName;

	if(!Count || !PutCtrlWord(CWF_GRP, i_fonttbl))	// Start font table group
		goto CleanUp;

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

//		if (ptf->sCodePage)
//			if (! PutCtrlWord(CWF_VAL, i_cpg, ptf->sCodePage ) )
//				goto CleanUp;

		// Define font family
		m			 = ptf->bPitchAndFamily >> 4;
		szFamily	 = rgKeyword[rgiszFamily[m < 6 ? m : 0]].szKeyword;
		szTaggedName = NULL;

		// check to see if this is a tagged font
		if (!ptf->bCharSet ||
			!FindTaggedFont(ptf->szName, ptf->bCharSet, &szTaggedName))
		{
			szTaggedName = NULL;
		}

		pitch = ptf->bPitchAndFamily & 0xF;					// Write font
		if (!printF(szBeginFontEntryFmt, itf, szFamily))	//  entry, family,
			goto CleanUp;
		_fNeedDelimeter = TRUE;
		if (pitch && !PutCtrlWord(CWF_VAL, i_fprq, pitch))	//  and pitch
			goto CleanUp;

		if (!ptf->sCodePage && ptf->bCharSet)
		{
			ptf->sCodePage = GetCodePage(ptf->bCharSet);
		}

#ifdef PWD_JUPITER
        // GuyBark: If this is a J font, then store the id here so we can 
        // select it later if necessary when outputting J text chunks.
        if((_pwdDefaultJFont == -1) && (ptf->sCodePage == 932))
        {
            _pwdDefaultJFont = itf;
        }
#endif // PWD_JUPITER

		// Write charset. Win32 uses ANSI_CHARSET to mean the default Windows
		// character set, so find out what it really is

		extern BYTE bCharSetANSI;

		if(ptf->bCharSet != DEFAULT_CHARSET)
		{

⌨️ 快捷键说明

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