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

📄 rtfwrit.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			if(!PutCtrlWord(CWF_VAL, i_fcharset, ptf->bCharSet))
			{
				goto CleanUp;
			}

			// We want to skip the \cpgN output if we've already output a \fcharsetN
			// tag.  This is to accomodate RE1.0, which can't handle some \cpgN tags
			// properly.  Specifically, when RE1.0 parses the \cpgN tag it does a 
			// table lookup to obtain a charset value corresponding to the codepage.
			// Turns out the codepage/charset table for RE1.0 is incomplete and RE1.0
			// maps some codepages to charset 0, trouncing the previously read \fcharsetN
			// value.
			goto WroteCharSet;
		}

		if (ptf->sCodePage && !PutCtrlWord (CWF_VAL, i_cpg, ptf->sCodePage))
		{
			goto CleanUp;
		}

WroteCharSet:

#ifdef PWD_JUPITER

        // GuyBark:
        // Check if the font has a charset that means a font decoration should be
        // output with the name. Word 95 uses the decoration. Word 97 will just
        // ignore it.

        LPSTR pszDecoration = NULL;

        // No decoration needed for plain ol' Western ANSI fonts. Don't mess with 
        // the name if we're taking any special action with it either.

        if(ptf->bCharSet && !szTaggedName && !ptf->fNameIsDBCS)
        {
            int i = 0;

            // Word97 uses a decoration of "Turkish, rather than "Tur". So we'll 
            // use that too. We hit "Tur" first in the decoration array. 
            // Note: the Office converters check for "Turkish" so that may mean, 
            // but we're better off emulating Word 97.

            // For all the decorations we handle...
            while(fontDec[i].pszName)
            {
                // Is the charset of the font we're outputting the same as the decoration's?
                if(ptf->bCharSet == fontDec[i].charset)
                {
                    // Yes! So output the decoration after the name.
                    pszDecoration = fontDec[i].pszName;

                    break;
                }

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

		if (szTaggedName)							
		{											
			// Have a tagged font:  write out group with real name followed by tagged name
			if(!PutCtrlWord(CWF_AST, i_fname) ||	
				WritePcData(ptf->szName, ptf->sCodePage, ptf->fNameIsDBCS) ||			
				!Puts(szEndFontEntry, sizeof(szEndFontEntry) - 1) ||
				WritePcData(szTaggedName, ptf->sCodePage, ptf->fNameIsDBCS) ||
				!Puts(szEndFontEntry, sizeof(szEndFontEntry) - 1))
			{
				goto CleanUp;
			}
		}
		else if(WritePcData(ptf->szName, ptf->sCodePage, ptf->fNameIsDBCS) ||
#ifdef PWD_JUPITER
               // GuyBark: We may have a decoration to output with the font name.
               (pszDecoration && !Puts(pszDecoration, strlen(pszDecoration))) ||
#endif // PWD_JUPITER
					!Puts(szEndFontEntry, sizeof(szEndFontEntry) - 1))
		// If non-tagged font just write name out
		{
			goto CleanUp;
		}
	}

	Puts(szEndGroupCRLF, sizeof(szEndGroupCRLF) - 1);							// End font table group

CleanUp:
	return _ecParseError;
}

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

	LONG		Count = _colors.Count();
	COLORREF	clrf;
	LONG		iclrf;

    // GuyBark Jupiter 35396: Now that we allow autocolor, we must ALWAYS
    // output a color table, even if it only has the one ';' entry.
#ifdef PWD_JUPITER
	if (!PutCtrlWord(CWF_GRP, i_colortbl)	// Start color table group
#else
	if (!Count || !PutCtrlWord(CWF_GRP, i_colortbl)	// Start color table group
#endif // PWD_JUPITER
		|| !PutChar(';'))							//  with null first entry
	{
		goto CleanUp;
	}

	for(iclrf = 0; iclrf < Count; iclrf++)
	{
		clrf = _colors.GetAt(iclrf);
		if (!printF(szColorEntryFmt,
					GetRValue(clrf), GetGValue(clrf), GetBValue(clrf)))
			goto CleanUp;
	}

	Puts(szEndGroupCRLF,sizeof(szEndGroupCRLF) -1);		// End color table group

CleanUp:
	return _ecParseError;
}

/*
 *	CRTFWrite::WriteCharFormat(pCF)
 *
 *	@mfunc
 *		Write deltas between CCharFormat <p pCF> and the previous CCharFormat
 *		given by _CF, and then set _CF = *<p pCF>.
 *
 *	@rdesc
 *		EC			The error code
 *
 *	@devnote
 *		For optimal output, could write \\plain and use deltas relative to
 *		\\plain if this results in less output (typically only one change
 *		is made when CF changes, so less output results when compared to
 *		previous CF than when compared to \\plain).
 */
EC CRTFWrite::WriteCharFormat(
	const CCharFormat * pCF)		// @parm Ptr to CCharFormat
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteCharFormat");

	DWORD	dwEffects = pCF->dwEffects;
	DWORD	dwChanges = dwEffects ^ _CF.dwEffects;
	LONG	i;										// Counter
	LONG	iFormat;
	LONG	iValue;									// Control-word value
	LONG	i_sz;									// Temp ctrl string index
	DWORD	UType;									// Underline type
	LONG	yOffset = pCF->yOffset;

    // GuyBark Jupiter J
    // For JupiterJ I've added two new numbered list types. This mean 
    // I had to change all the i_xx array to Word arrays not bytes.
//	AssertSz(cKeywords < 256,
//		"CRTFWrite::WriteCharFormat: change BYTE i_xx to WORD");

	if (dwChanges & CFE_AUTOCOLOR ||				// Change in autocolor
		pCF->crTextColor != _CF.crTextColor)		//  or text color
	{
		iValue = 0;									// Default autocolor
		if(!(dwEffects & CFE_AUTOCOLOR))			// Make that text color
			iValue = LookupColor(pCF->crTextColor) + 1;
		if(!PutCtrlWord(CWF_VAL, i_cf, iValue))
			goto CleanUp;
	}

	if (dwChanges & CFE_AUTOBACKCOLOR ||			// Change in autobackcolor
		pCF->crBackColor != _CF.crBackColor)		//  or backcolor
	{
		iValue = 0;									// Default autobackcolor
		if(!(dwEffects & CFE_AUTOBACKCOLOR))		// Make that back color
			iValue = LookupColor(pCF->crBackColor) + 1;
		if(!PutCtrlWord(CWF_VAL, i_highlight, iValue))
			goto CleanUp;
	}

	if (pCF->lcid		!= _CF.lcid &&
		!PutCtrlWord(CWF_VAL, i_lang, LANGIDFROMLCID((WORD)pCF->lcid)) ||
		pCF->sSpacing	!= _CF.sSpacing &&
		!PutCtrlWord(CWF_VAL, i_expndtw, pCF->sSpacing)		||
		/* FUTURE (alexgo): This code is incorrect and we don't
		yet handle the Style table.  We may want to support this
		better in a future version.
		pCF->sStyle		!= _CF.sStyle && pCF->sStyle > 0    &&
		!PutCtrlWord(CWF_VAL, i_cs, pCF->sStyle)			|| */
		pCF->bAnimation	!= _CF.bAnimation &&
		!PutCtrlWord(CWF_VAL, i_animtext, pCF->bAnimation)	||
		/* FUTURE (alexgo): this code doesn't work yet, as we don't
		output the revision table.  We may want to support this 
		better in a future version
		pCF->bRevAuthor	!= _CF.bRevAuthor &&
		!PutCtrlWord(CWF_VAL, i_revauth, pCF->bRevAuthor)	|| */
		pCF->wKerning	!= _CF.wKerning &&
		!PutCtrlWord(CWF_VAL, i_kerning, pCF->wKerning/10) )
	{
		goto CleanUp;
	}

	UType = _CF.bUnderlineType;						// Handle all underline
	if (UType <= CUNDERLINES &&						//  known and
		dwEffects & CFM_UNDERLINE &&				//  active changes
		(UType != pCF->bUnderlineType ||			// Type change while on
		 dwChanges & CFM_UNDERLINE))				// Turn on
	{
		dwChanges &= ~CFE_UNDERLINE;				// Suppress underline
		i = pCF->bUnderlineType;
		if(i)
			i--;
		if(!PutCtrlWord(CWF_STR,
			rgiszUnderlines[i]))					// action in next for()
				goto CleanUp;						// Note: \ul0 turns off
	}												//  all underlining

													// This must be before next stuff
	if(dwChanges & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT))//  change in sub/sup
	{												// status	
	 	i_sz = dwEffects & CFE_SUPERSCRIPT ? i_super
	    	 : dwEffects & CFE_SUBSCRIPT   ? i_sub
	       	 : i_nosupersub;
     	if(!PutCtrlWord(CWF_STR, i_sz))
			goto CleanUp;
	}

	dwChanges &= ((1 << CEFFECTS) - 1) & ~CFE_LINK;	// Output keywords for
	for(i = CEFFECTS;								//  effects that changed
		dwChanges && i--;							// rgszEffects[] contains
		dwChanges >>= 1, dwEffects >>= 1)			//  effect keywords in
	{												//  order max CFE_xx to
		if(dwChanges & 1)							//  min CFE-xx
		{											// Change from last call
			iValue = dwEffects & 1;					// If effect is off, write
			iFormat = iValue ? CWF_STR : CWF_VAL;	//  a 0; else no value
			if(!PutCtrlWord(iFormat,
				rgiszEffects[i], iValue))
					goto CleanUp;
		}
	}

	if(yOffset != _CF.yOffset)						// Change in base line 
	{												// position 
		yOffset /= 10;								// Default going to up
		i_sz = i_up;
		iFormat = CWF_VAL;
		if(yOffset < 0)								// Make that down
		{
			i_sz = i_dn;
			yOffset = -yOffset;
		}
		if(!PutCtrlWord(iFormat, i_sz, yOffset))
			goto CleanUp;
	}

	if (pCF->bPitchAndFamily != _CF.bPitchAndFamily ||	// Change in font
		pCF->bCharSet		 != _CF.bCharSet		||
		lstrcmp(pCF->szFaceName, _CF.szFaceName))
	{
		iValue = LookupFont(pCF);
		if(iValue < 0 || !PutCtrlWord(CWF_VAL, i_f, iValue))
			goto CleanUp;

#ifdef PWD_JUPITER
        // GuyBark: Keep a track of the current font selected.
        _pwdCurrentFont = iValue;
#endif // PWD_JUPITER
    }

	if (pCF->yHeight != _CF.yHeight)					// Change in font size
	{
		iValue = (pCF->yHeight + (pCF->yHeight > 0 ? 5 : -5))/10;
		if(!PutCtrlWord(CWF_VAL, i_fs, iValue))
			goto CleanUp;
	}

	_CF = *pCF;									// Update previous CCharFormat

CleanUp:
	return _ecParseError;
}

/*
 *	CRTFWrite::WriteParaFormat(prtp)
 *
 *	@mfunc
 *		Write out attributes specified by the CParaFormat <p pPF> relative
 *		to para defaults (probably produces smaller output than relative to
 *		previous para format and let's you redefine tabs -- no RTF kill
 *		tab command	except \\pard)
 *
 *	@rdesc
 *		EC				The error code
 */
EC CRTFWrite::WriteParaFormat(
	const CRchTxtPtr * prtp)	// @parm Ptr to rich-text ptr at current cp
{
	TRACEBEGIN(TRCSUBSYSRTFW, TRCSCOPEINTERN, "CRTFWrite::WriteParaFormat");

	Assert(_ped);

	//if(!_fRangeHasEOP)							// Don't write para info if
	//	return _ecParseError;					//  range has no EOPs

	const CParaFormat * pPFPrev = _pPF;
	const CParaFormat * pPF = _pPF = prtp->GetPF();

    if (NULL == pPF)
        return _ecParseError;
        
	BOOL	fInTable = pPF->InTable();
	LONG	c;					  				// Temporary count
	LONG	cTab = pPF->cTabCount;
	DWORD	dwEffects;
	DWORD	dwRule	= pPF->bLineSpacingRule;
	LONG	dy		= pPF->dyLineSpacing;
	LONG	i_t, i, j, k;
	LONG	tabAlign, tabLead, tabPos;
	LONG	lDocDefaultTab = _ped->GetDefaultTab();

	if(!lDocDefaultTab)
		lDocDefaultTab = lDefaultTab;

	if (cTab == 1 && pPF->rgxTabs[0] == lDocDefaultTab + (LONG)PFT_DEFAULT ||
		CheckInTable(FALSE))
	{
		cTab = 0;								// Suppress \tab output
	}

	AssertSz(cTab >= 0 && cTab <= MAX_TAB_STOPS,
		"CRTFW::WriteParaFormat: illegal cTabCount");

	// Exchange's IMC keys on the \protect tag when it does
	//	its reply-ticking for mail being sent to Internet recipients.  
	//	Paragraphs following a \pard and containing a \protect tag are 
	//	reply-ticked, so we must ensure that each \pard in a protected range
	//	is followed by a \protect tag.

	if (_CF.dwEffects & CFE_PROTECTED && !PutCtrlWord(CWF_VAL, i_protect, 0) ||
		!PutCtrlWord(CWF_STR, i_pard) ||			// Reset para attributes
		_CF.dwEffects & CFE_PROTECTED && !PutCtrlWord(CWF_STR, i_protect))
	{
		goto CleanUp;
	}

	if(fInTable)
	{
		if(_fRangeHasEOP && !PutCtrlWord(CWF_STR, i_intbl))
			goto CleanUp;
	}
	else if(PutBorders(FALSE))
		goto CleanUp;

	if(pPF->wShadingStyle)
	{
		i = pPF->wShadingStyle & 15;				// Shading patterns
		j = (pPF->wShadingStyle >> 6) & 31;			// Shading forecolor
		k = pPF->wShadingStyle >> 11;				// Shading backcolor
		if (i && i <= CSHADINGSTYLES &&
			!PutCtrlWord(CWF_STR, rgiszShadingStyles[i - 1]) ||
			j && !PutCtrlWord(CWF_VAL, i_cfpat, LookupColor(g_Colors[j-1]) + 1) ||
			k && !PutCtrlWord(CWF_VAL, i_cbpat, LookupColor(g_Colors[k-1]) + 1))
		{
			goto CleanUp;
		}
	}
	if(pPF->wShadingWeight && !PutCtrlWord(CWF_VAL, i_shading, pPF->wShadingWeight))
		goto CleanUp;

	// Paragraph numbering
	_fBullet = _fBulletPending = FALSE;
	_nNumber = pPF->UpdateNumber(_nNumber, pPFPrev);

	if(pPF->wNumbering)							// Write numbering info
	{
		LONG iFont = _symbolFont;
		if(pPF->IsListNumbered())
		{
			const CCharFormat *pCF;
			WCHAR szNumber[CCHMAXNUMTOSTR];

			CTxtPtr		  rpTX(prtp->_rpTX);
			CFormatRunPtr rpCF(prtp->_rpCF);

			rpCF.AdvanceCp(rpTX.FindEOP(tomForward));
			rpCF.AdjustBackward();
			pCF = _ped->GetCharFormat(rpCF.GetFormat());
			iFont = LookupFont(pCF);
			if(iFont < 0)
			{
				iFont = 0;
				TRACEERRORSZ("CWRTFW::WriteParaFormat: illegal bullet font");
			}
			_nFont = iFont;
			// TODO: make the following smarter, i.e., may need to increment
			// _nNumber instead of resetting it to 1.
			_cpg = GetCodePage(pCF->bCharSet);

			i = 0;

            // GuyBark JupiterJ: Assume we want everything before sequence value
//			if(pPF->wNumbering <= tomListNumberAsUCRoman)
            if(pPF->wNumbering < tomListNumberAsSequence)
				i = pPF->wNumbering - tomListNumberAsArabic;

			WORD  wStyle = pPF->wNumberingStyle & 0xF00;

			WCHAR ch = (wStyle == PFNS_PARENS || wStyle == PFNS_PAREN) ? ')'
					 : (wStyle == PFNS_PERIOD) ? '.' : 0;
			if(wStyle != PFNS_NONUMBER)			  // Unless number suppressed
			{									  //  write \pntext group
				pPF->NumToStr(szNumber, _nNumber);
				if (!printF(szBeginNumberGroup, iFont) ||
					WritePcData(szNumber, _cpg, FALSE) ||	
					!printF(szEndNumberGroup))
				{
					goto CleanUp;
				}
			}

			if (!printF(szBeginNumberFmt,
						wStyle == PFNS_NONUMBER ? "cont" : "body",
						iFont, pPF->wNumberingTab,
						pPF->wNumberingStart)				||
				!PutCtrlWord(CWF_STR, rgiszNumberStyle[i])	||
				wStyle == PFNS_PARENS && !printF(szpntxtb)	||
				ch && !printF(szpntxta, ch)					||
				!printF(szEndGroupCRLF))
			{
				goto CleanUp;
			}
		}
		else
		{
			if (!printF(szBulletGroup, iFont) ||
				!printF(szBulletFmt,   iFont, pPF->wNumberingTab))
			{
				goto CleanUp;
			}
		}
		_fBullet = TRUE;
	}

	// Put out para indents. RTF first indent = -PF.dxOffset
	// RTF left indent = PF.dxStartIndent + PF.dxOffset

	if(IsHeadingStyle(pPF->sStyle) && !PutCtrlWord(CWF_VAL, i_s, -pPF->sStyle-1))
		goto CleanUp;
		

⌨️ 快捷键说明

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