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

📄 rtfwrit.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//
/*
 *	@doc INTERNAL
 *
 *	@module	RTFWRIT.CPP - RichEdit RTF Writer (w/o objects) |
 *
 *		This file contains the implementation of the RTF writer
 *		for the RichEdit control, except for embedded objects,
 *		which are handled mostly in rtfwrit2.cpp
 *
 *	Authors: <nl>
 *		Original RichEdit 1.0 RTF converter: Anthony Francisco <nl>
 *		Conversion to C++ and RichEdit 2.0:  Murray Sargent <nl>
 *		Lots of enhancements: Brad Olenick <nl>
 *
 */

#include "_common.h"
#include "_rtfwrit.h"
#include "_objmgr.h"
#include "_coleobj.h"

ASSERTDATA

extern KEYWORD rgKeyword[];

//========================= Global String Constants ==================================

BYTE bCharSetANSI = ANSI_CHARSET;				// ToDo: make more general

#ifdef DEBUG
// Quick way to find out what went wrong: rgszParseError[ecParseError]
//
CHAR *	rgszParseError[] =
{
	"No error",
	"Can't convert to Unicode",				// FF
	"Color table overflow",					// FE
	"Expecting '\\rtf'",					// FD
	"Expecting '{'",						// FC
	"Font table overflow",					// FB
	"General failure",						// FA
	"Keyword too long",						// F9
	"Lexical analyzer initialize failed",	// F8
	"No memory",							// F7
	"Parser is busy",						// F6
	"PutChar() function failed",			// F5
	"Stack overflow",						// F4
	"Stack underflow",						// F3
	"Unexpected character",					// F2
	"Unexpected end of file",				// F1
	"Unexpected token",						// F0
	"UnGetChar() function failed",			// EF
	"Maximum text length reached",			// EE
	"Streaming out object failed",			// ED
	"Streaming in object failed",			// EC
	"Truncated at CR or LF",				// EB
	"Format-cache failure",					// EA
	NULL									// End of list marker
};

CHAR * szDest[] =
{
	"RTF",
	"Color Table",
	"Font Table",
	"Binary",
	"Object",
	"Object Class",
	"Object Name",
	"Object Data",
	"Field",
	"Field Result",
	"Field Instruction",
	"Symbol",
	"Paragraph Numbering",
	"Picture"
};

#endif

// Most control-word output is done with the following printf formats
static const CHAR * rgszCtrlWordFormat[] =
{
	"\\%s", "\\%s%d", "{\\%s", "{\\*\\%s", "{\\%s%d"
};

// Special control-word formats
static const CHAR szBeginFontEntryFmt[]	= "{\\f%d\\%s";
static const CHAR szBulletGroup[]		= "{\\pntext\\f%d\\'B7\\tab}";
static const CHAR szBulletFmt[]			= "{\\*\\pn\\pnlvlblt\\pnf%d\\pnindent%d{\\pntxtb\\'B7}}";
static const CHAR szBeginNumberGroup[]	= "{\\pntext\\f%d ";
static const CHAR szEndNumberGroup[]	= "\\tab}";
static const CHAR szBeginNumberFmt[]	= "{\\*\\pn\\pnlvl%s\\pnf%d\\pnindent%d\\pnstart%d";
static const CHAR szpntxtb[]			= "{\\pntxtb(}";
static const CHAR szpntxta[]			= "{\\pntxta%c}";
static const CHAR szColorEntryFmt[]		= "\\red%d\\green%d\\blue%d;";
static const CHAR szEndFontEntry[]		= ";}";
       const CHAR szEndGroupCRLF[]		= "}\r\n";
static const CHAR szEscape2CharFmt[]	= "\\'%02x\\'%02x";
static const CHAR szLiteralCharFmt[]	= "\\%c";
static const CHAR szPar[]				= "\\par\r\n";
static const CHAR szObjPosHolder[] 		= "\\objattph\\'20";
static const CHAR szDefaultFont[]		= "\\deff0";
static const CHAR szHorzdocGroup[]		= "{\\horzdoc}";
static const CHAR szNormalStyle[]		= "{ Normal;}";
static const CHAR szHeadingStyle[]		= "{\\s%d heading %d;}";
static const CHAR szEndRow[]			= "\\row\r\n";
static const CHAR szPwdComment[]		= "{\\*\\pwdcomment ";

#define szEscapeCharFmt		&szEscape2CharFmt[6]

const WORD rgiszTerminators[] =
{	i_cell, 0, i_tab, 0, i_line, i_page};

// Keep these indices in sync with the special character values in _common.h
const WORD rgiszSpecial[] =
{
	i_enspace,
	i_emspace,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	i_endash,		
	i_emdash,
	0,
	0,
	0,
	i_lquote, 
	i_rquote,
	0,
	0,
	i_ldblquote, 
	i_rdblquote,
	0,
	0,
	0,
	0,
	i_bullet
};

const WORD rgiszEffects[] =							
{													// Effects keywords
	i_revised, i_disabled, i_impr, i_embo,			// Ordered max CFE_xx to
	i_shad, i_outl, i_v, i_caps, i_scaps,		 	//  min CFE_xx
	i_disabled, i_protect, i_strike, i_ul, i_i,	i_b	// (see WriteCharFormat())
};													

#define CEFFECTS	ARRAY_SIZE(rgiszEffects)

const WORD rgiszPFEffects[] =						// PF effects keywords
{													// Ordered max PFE_xx to
	i_collapsed, i_sbys, i_hyphpar, i_nowidctlpar,	//  min PFE_xx
	i_noline, i_pagebb, i_keepn, i_keep, i_rtlpar
};													// (see WriteParaFormat())

#define CPFEFFECTS	ARRAY_SIZE(rgiszPFEffects)

const WORD rgiszUnderlines[] =
{
	i_ul, i_ulw, i_uldb, i_uld,						// Std Word underlines
	i_uldash, i_uldashd, i_uldashdd, i_ulwave, i_ulth, i_ulhair
};

#define CUNDERLINES	ARRAY_SIZE(rgiszUnderlines)

const WORD rgiszFamily[] =							// Font family RTF name
{													//  keywords in order of
	i_fnil, i_froman, i_fswiss, i_fmodern,			//  bPitchAndFamily
	i_fscript, i_fdecor
//  , i_ftech, i_fbidi								// TODO
};

const WORD rgiszAlignment[] =						// Alignment keywords
{													// Keep in sync with
	i_ql, i_qr,	i_qc, i_qj							//  alignment constants
};

const WORD rgiszTabAlign[] =						// Tab alignment keywords
{													// Keep in sync with tab
	i_tqc, i_tqr, i_tqdec							//  alignment constants
};

const WORD rgiszTabLead[] =							// Tab leader keywords
{													// Keep in sync with tab
	i_tldot, i_tlhyph, i_tlul, i_tlth, i_tleq		//  leader constants
};

const WORD rgiszNumberStyle[] =						// Numbering style keywords
{													// Keep in sync with TOM
	i_pndec, i_pnlcltr, i_pnucltr,					//  values 
	i_pnlcrm, i_pnucrm, 
    i_pnaiueod, i_pnirohad    // GuyBark JupiterJ: added these
};

const WORD rgiszBorders[] =							// Border combination keywords
{													
	i_box,
	i_brdrt, i_brdrl, i_brdrb, i_brdrr,
	i_trbrdrt, i_trbrdrl, i_trbrdrb, i_trbrdrr,
	i_clbrdrt, i_clbrdrl, i_clbrdrb, i_clbrdrr
};

const WORD rgiszBorderStyles[] =					// Border style keywords
{													
	i_brdrdash, i_brdrdashsm, i_brdrdb, i_brdrdot,
	i_brdrhair, i_brdrs, i_brdrth, i_brdrtriple
};
#define CBORDERSTYLES ARRAY_SIZE(rgiszBorderStyles)

const WORD rgiszBorderEffects[] =					// Border effect keywords
{													
	i_brdrbar, i_brdrbtw, i_brdrsh					// Reverse order from bits
};

const WORD rgiszShadingStyles[] =					// Shading style keywords
{													
	i_bgbdiag, i_bgcross, i_bgdcross, i_bgdkbdiag,
	i_bgdkcross, i_bgdkdcross, i_bgdkfdiag, i_bgdkhoriz,
	i_bgdkvert, i_bgfdiag, i_bghoriz, i_bgvert 
};
#define CSHADINGSTYLES ARRAY_SIZE(rgiszShadingStyles)

// RGB with 2 bits per color type (in BGR order)
const COLORREF g_Colors[] =
{
	RGB(  0,   0,   0),	// \red0\green0\blue0
	RGB(  0,   0, 255),	// \red0\green0\blue255
	RGB(  0, 255, 255),	// \red0\green255\blue255
	RGB(  0, 255,   0),	// \red0\green255\blue0
	RGB(255,   0, 255),	// \red255\green0\blue255
	RGB(255,   0,   0),	// \red255\green0\blue0
	RGB(255, 255,   0),	// \red255\green255\blue0
	RGB(255, 255, 255),	// \red255\green255\blue255
	RGB(  0,   0, 128),	// \red0\green0\blue128
	RGB(  0, 128, 128),	// \red0\green128\blue128
	RGB(  0, 128,   0),	// \red0\green128\blue0
	RGB(128,   0, 128),	// \red128\green0\blue128
	RGB(128,   0,   0),	// \red128\green0\blue0
	RGB(128, 128,   0),	// \red128\green128\blue0
	RGB(128, 128, 128),	// \red128\green128\blue128
	RGB(192, 192, 192),	// \red192\green192\blue192
};

/*
 *	CRTFWrite::MapsToRTFKeywordW(wch)
 *
 *	@mfunc
 *		Returns a flag indicating whether the character maps to an RTF keyword
 *
 *	@rdesc
 *		BOOL			TRUE if char maps to RTF keyword
 */
inline BOOL CRTFWrite::MapsToRTFKeywordW(WCHAR wch)
{
	return
		IN_RANGE(TAB, wch, CR) ||
#ifdef PWD_JUPITER
        // GuyBark Jupiter: Handle the special character for CRLF in table cells.
        wch == PWD_CRLFINCELL ||
#endif // PWD_JUPITER
		wch == CELL ||
		wch == CELL ||
		wch == BSLASH ||
		wch == LBRACE || 
		wch == RBRACE ||
		IN_RANGE(ENSPACE, wch, EMSPACE) ||
		IN_RANGE(ENDASH, wch, EMDASH) ||
		IN_RANGE(LQUOTE, wch, RQUOTE) ||
		IN_RANGE(LDBLQUOTE, wch, RDBLQUOTE) ||
		wch == BULLET ||
		wch == chOptionalHyphen ||
		wch == chNonBreakingSpace;
}

/*
 *	CRTFWrite::MapsToRTFKeywordA(ch)
 *
 *	@mfunc
 *		Returns a flag indicating whether the character maps to an RTF keyword
 *
 *	@rdesc
 *		BOOL			TRUE if char maps to RTF keyword
 */
inline BOOL CRTFWrite::MapsToRTFKeywordA(char ch)
{
	return IN_RANGE(TAB, ch, CR) ||
		ch == CELL ||
		ch == BSLASH ||
		ch == LBRACE || 
		ch == RBRACE;
}

/*
 *	CRTFWrite::MapToRTFKeywordW(pv, cch, iCharEncoding)
 *
 *	@mfunc
 *		Examines the first character in the string pointed to by pv and
 *		writes out the corresponding RTF keyword.  In situations where
 *		the first and subsequent characters map to a single keyword, we
 *		return the number of additional characters used in the mapping.
 *
 *	@rdesc
 *		int		indicates the number of additional characters used when
 *				the mapping to an RTF keyword involves > 1 characters.
 */
int CRTFWrite::MapToRTFKeyword(
	void *	pv,				//@parm ptr to ansi or Unicode string
	int		cch,
	int		iCharEncoding)
{
	Assert(iCharEncoding == MAPTOKWD_ANSI || iCharEncoding == MAPTOKWD_UNICODE);

	WCHAR ch = ((iCharEncoding == MAPTOKWD_ANSI) ? *(char *)pv : *(WCHAR *)pv);
	int cchRet = 0;

	Assert((iCharEncoding == MAPTOKWD_ANSI) ? MapsToRTFKeywordA(ch) : MapsToRTFKeywordW(ch));

	switch(ch)
	{
#ifdef PWD_JUPITER
        // GuyBark Jupiter: We've hit the special character inserting when 
        // reading the file, to represent a CRLF in a table cell.
        case PWD_CRLFINCELL:
        {
            // Mimic the rtf output by Word97 in this situation.
            char szParInTable[] = "\r\n\\par";
            
            Puts(szParInTable, strlen(szParInTable));

            break;
        }
#endif // PWD_JUPITER
		case BULLET:
		case EMDASH:
		case EMSPACE:
		case ENDASH:
		case ENSPACE:
		case LDBLQUOTE:
		case LQUOTE:
		case RDBLQUOTE:
		case RQUOTE:
			Assert(ch > 0xFF);

			if(iCharEncoding != MAPTOKWD_ANSI)
			{
				AssertSz(rgiszSpecial[ch - ENSPACE] != 0,
					"CRTFWrite::WriteText(): rgiszSpecial out-of-sync");
				PutCtrlWord(CWF_STR, rgiszSpecial[ch - ENSPACE]);
			}
			break;

		case FF:
		case VT:
		case TAB:
		case CELL:

			PutCtrlWord(CWF_STR, rgiszTerminators[ch - CELL]);
			break;

		case CR:
		{
			WCHAR ch1;
			WCHAR ch2;

			if(iCharEncoding == MAPTOKWD_ANSI)
			{
				char *pch = (char *)pv;
				ch1 = pch[1];
				ch2 = pch[2];
			}
			else
			{
				WCHAR *pch = (WCHAR *)pv;
				ch1 = pch[1];
				ch2 = pch[2];
			}

			if(cch > 1 && ch1 == CR && ch2 == LF)
			{
				// Translate CRCRLF	to a blank (represents soft line break)
				PutChar(' ');
				cchRet = 2;
				break;
			}
			if(cch && ch1 == LF)		// Ignore LF after CR
			{
				cchRet = 1;
			}							
			if(_pPF->InTable())			// CR terminates a row in our simple
			{							//  table model, so output \row
				Puts(szEndRow, sizeof(szEndRow) - 1);
				_fCheckInTable = TRUE;

				break;
			}
		}								// Fall thru to LF (EOP) case

		case LF:
			Puts(szPar, sizeof(szPar) - 1);
			if(_fBullet)
			{
				if(cch > 0)
				{
					if(!_nNumber) 
						printF(szBulletGroup, _symbolFont);

					else if(!_pPF->IsNumberSuppressed())
					{
						WCHAR szNumber[CCHMAXNUMTOSTR];
						_pPF->NumToStr(szNumber, ++_nNumber);
						printF(szBeginNumberGroup, _nFont);
						WritePcData(szNumber, _cpg, FALSE);
						printF(szEndNumberGroup);
					}
				}
				else
					_fBulletPending = TRUE;
			}
			break;

		case chOptionalHyphen:
			ch = '-';					// Fall thru to printFLiteral

printFLiteral:
		case BSLASH:
		case LBRACE:
		case RBRACE:
			printF(szLiteralCharFmt, ch);
			break;

		case chNonBreakingSpace:
			ch = '~';
			goto printFLiteral;
	}
	
	return cchRet;

⌨️ 快捷键说明

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