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

📄 rtfwrit2.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
/*
 *	rtfwrit2.cpp
 *
 *	Description:
 *		This file contains the embedded-object implementation of the RTF
 *		writer for the RICHEDIT subsystem.
 *
 *	Authors:
 *		Original RichEdit 1.0 RTF converter: Anthony Francisco
 *		Conversion to C++ and RichEdit 2.0:  Murray Sargent
 */

#include "_common.h"


#include "_rtfwrit.h"
#include "_coleobj.h"

ASSERTDATA

// ************** V-GUYB: Add this for converting pictures to 2bpp during stream out.
#if defined(CONVERT2BPP) 

#define PWDV1_BPP   2

typedef struct 
{
    BITMAPINFOHEADER bmih;
    RGBQUAD          colors[4];
}
BMI2BPP;

const BYTE ColorTable2bpp[] = 
{
    0x00, 0x00, 0x00, 0x00, 
    0x55, 0x55, 0x55, 0x00, 
    0xAA, 0xAA, 0xAA, 0x00, 
    0xFF, 0xFF, 0xFF, 0x00
};
#endif // CONVERT2BPP
// ************** V-GUYB: End of conversion stuff.

static const CHAR szHexDigits[] = "0123456789abcdef";

static const CHAR szLineBreak[] = "\r\n";

const WORD ObjectKeyWordIndexes [] =
{
	i_objw,i_objh,i_objscalex, i_objscaley, i_objcropl, i_objcropt, i_objcropr, i_objcropb
} ;

const WORD PictureKeyWordIndexes [] =
{
	i_picw,i_pich,i_picscalex, i_picscaley, i_piccropl, i_piccropt, i_piccropr, i_piccropb

} ;

// TODO join with rtfwrit.cpp

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

static const WORD IndexROT[] =
{
	i_wbitmap,
	i_wmetafile,
	i_dibitmap,
	i_objemb,
	i_objlink,
	i_objautlink
};


TFI *CRTFConverter::_rgtfi = NULL;				// @cmember Pointer to the first font substitute record
INT CRTFConverter::_ctfi = 0;				    // @cmember Number of the font substitute records
TCHAR *CRTFConverter::_pchFontSubInfo = NULL;		// @cmember Font name information


// internal table to insert charset into _rgtfi under winNT
typedef		struct
{
	TCHAR*	szLocaleName;
	BYTE	bCharSet;
} NTCSENTRY;

const NTCSENTRY	mpszcs[] =
{
	{ TEXT("cyr"),		204 },		// all lower case so we don't have to waste time
	{ TEXT("ce"),		238 },		// doing a tolower below - Exchange2 800
	{ TEXT("greek"),	161 },
	{ NULL,				0 }			// sentinel
};

#define		cszcs	(sizeof(mpszcs)/sizeof(mpszcs[0]))


/* 
 *  Service  RemoveAdditionalSpace (sz)
 *
 *  Purpose: 
 *			 Remove first and last space from the string 
 *			 Only one space will remain between words
 *
 *	Argument 
 *			 sz characters string
 */
void RemoveAdditionalSpace(TCHAR *sz)
{
	TRACEBEGIN(TRCSUBSYSRTFR, TRCSCOPEINTERN, "RemoveAdditionalSpace");

	TCHAR *szSource = sz;
	TCHAR *szDestination = sz;

	while(*szSource == TEXT(' ') || *szSource == TAB)
	{
		*szSource++;
	}

	while(*szSource)
	{	 
		if(*szSource != TEXT(' ') && *szSource != TAB)
		{
			*szDestination++ = *szSource++;
		}
		else
		{
			*szDestination++ = TEXT(' ');
			szSource++;

			while(*szSource == TEXT(' ') || *szSource == TAB)
			{
				*szSource++;
			}
	 	}
	}
	*szDestination = TEXT('\0');
}

/*
 *	CRTFConverter::FreeFontSubInfo(void)
 * 
 *	@mfunc	release any allocated memory for font substitutions
 *
 *	@rdesc	void
 */
void CRTFConverter::FreeFontSubInfo()
{
	FreePv(_pchFontSubInfo);
	FreePv(_rgtfi);
	_pchFontSubInfo = NULL;
	_rgtfi = NULL;
}

/*
 *		CRTFConverter::ReadFontSubInfo(void)
 *
 *		Purpose:				  
 *			Read the table of Font Substitutes and parse out the tagged fonts
 *
 *		Returns:
 *			BOOL  TRUE	if OK		
 */
void CRTFConverter::ReadFontSubInfo()
{
#ifndef NOFONTSUBINFO 
	CLock clock;
	int cchBuffer = 4096;	// random number that seems about right

	int cch;
	static const TCHAR szFontSubSection[] = TEXT("FontSubstitutes");
	TCHAR *pchTMax;

	if(_ctfi)
	{
		return;
	}

	AssertSz(!_rgtfi, "CRTFConverter::ReadFontSubInfo():  Who donated the rgtfi?");

	_pchFontSubInfo = (TCHAR *)PvAlloc(cchBuffer * sizeof(TCHAR), GMEM_FIXED);
	if(!_pchFontSubInfo)
	{
		goto Cleanup;
	}

next_try:
	cch = GetProfileSection(szFontSubSection, _pchFontSubInfo, cchBuffer);
	if(cch >= cchBuffer - 2)	// GetProfileSection() magic number 2
	{							
		// didn't fit, double the buffer size
		const INT cchT = cchBuffer * 2;

		if(cchT < cchBuffer)	// >32k 
		{
			goto Cleanup;
		}
		cchBuffer = cchT;
		_pchFontSubInfo = (TCHAR *)PvReAlloc(_pchFontSubInfo, cchT * sizeof(TCHAR));
		if(!_pchFontSubInfo)
		{
			goto Cleanup;
		}
		goto next_try;
	}
	else if(!cch)
	{
		*_pchFontSubInfo = 0;
	}

	_ctfi = cszcs;		// a preliminary guess
						// cszcs is used here only as a step in alloc

	_rgtfi = (TFI *)PvAlloc(_ctfi * sizeof(TFI), GMEM_FIXED);
	if(!_rgtfi)
	{
		goto Cleanup;
	}

	TFI *ptfi;
	TCHAR *pchT;

	pchT = _pchFontSubInfo;
	pchTMax = _pchFontSubInfo + cch;
	ptfi = &_rgtfi[0];

	TCHAR *szTaggedName;
	TCHAR *szNonTaggedName;
	BOOL fGotTaggedCharSet;
	BOOL fGotNonTaggedCharSet;
	BYTE bTaggedCharSet;
	BYTE bNonTaggedCharSet;
	PARSEFONTNAME iParseLeft;
	PARSEFONTNAME iParseRight;

	// parse the entries
	// we are interested in the following strings:
	//
	// <tagged font name> = <nontagged font name>
	//		(where <nontagged font name> = <tagged font name> - <tag>
	// <font1 name>,<font1 charset> = <font2 name>
	// <tagged font name> = <nontagged font name>,<nontagged font charset>
	//		(where <nontagged font charset> = <tag>)
	// <font1 name>,<font1 charset> = <font2 name>,<font2 charset>
	//		(where <font1 charset> == <font2 charset>)

	iParseLeft = iParseRight = PFN_SUCCESS;

	while(pchT < pchTMax && iParseLeft != PFN_EOF
						&& iParseRight != PFN_EOF)
	{
		fGotTaggedCharSet = FALSE;
		fGotNonTaggedCharSet = FALSE;

		if((iParseLeft = ParseFontName(pchT,
						pchTMax,
						TEXT('='),
						&szTaggedName, 
						bTaggedCharSet, 
						fGotTaggedCharSet, 
						&pchT)) == PFN_SUCCESS &&
			(iParseRight = ParseFontName(pchT, 
						pchTMax,
						TEXT('\0'),
						&szNonTaggedName, 
						bNonTaggedCharSet, 
						fGotNonTaggedCharSet, 
						&pchT)) == PFN_SUCCESS)
		{
			Assert(szTaggedName && szNonTaggedName);

			BYTE bCharSet;

			if(!fGotTaggedCharSet)
			{
				if(!FontSubstitute(szTaggedName, szNonTaggedName, &bCharSet))
				{
					continue;
				}
			}
			else
			{
				bCharSet = bTaggedCharSet;
			}

			if(fGotNonTaggedCharSet && bCharSet != bNonTaggedCharSet)
			{
				continue;
			}
					
			// We have a legitimate tagged/nontagged pair, so save it.
			ptfi->szTaggedName = szTaggedName;
			ptfi->szNormalName = szNonTaggedName;
			ptfi->bCharSet = bCharSet;

			ptfi++;

    		if(DiffPtrs(ptfi, &_rgtfi[0], TFI) >= (UINT)_ctfi)
			{
				// allocate some more
				_rgtfi = (TFI *)PvReAlloc(_rgtfi, (_ctfi + cszcs) * sizeof(TFI));
				if(!_rgtfi)
				{
					goto Cleanup;
				}
				ptfi = _rgtfi + _ctfi;
				_ctfi += cszcs;	
			}
		}
	}				
	
	_ctfi = DiffPtrs(ptfi, &_rgtfi[0], TFI);

	if (!_ctfi)
	{
		goto Cleanup;  // to cleanup alloc'd memory
	}
	return;

Cleanup:
	if(_pchFontSubInfo)
	{
		FreePv(_pchFontSubInfo);
		_pchFontSubInfo = NULL;
	}
	if(_rgtfi)
	{
		FreePv(_rgtfi);
		_rgtfi = NULL;
	}
	_ctfi = 0;
	return;
#endif // NOFONTSUBINFO
}


/*
 *		CRTFConverter::ParseFontName(pchBuf, pchBufMax, pszName, bCharSet, fSetCharSet, ppchBufNew, chDelimiter)
 *
 *		Purpose:
 *			Parses from the input buffer, pchBuf, a string of the form:
 *				{WS}*<font_name>{WS}*[,{WS}*<char_set>{WS}*]
 *			and sets:
 *				pszName = <font_name>
 *				bCharSet = <char_set>
 *				fSetCharSet = (bCharSet set by proc) ? TRUE : FALSE
 *				ppchBufNew = pointer to point in pchBuf after parsed font name
 *
 *		Returns:
 *			BOOL  TRUE	if OK		
 */
CRTFConverter::PARSEFONTNAME CRTFConverter::ParseFontName(TCHAR *pchBuf,	//@parm IN: buffer
								TCHAR *pchBufMax,	//@parm IN: last char in buffer
								TCHAR chDelimiter,	//@parm IN:	char which delimits font name
								TCHAR **pszName,	//@parm OUT: parsed font name
								BYTE &bCharSet,		//@parm OUT: parsed char set
								BOOL &fSetCharSet,	//@parm OUT: char set parsed?
								TCHAR **ppchBufNew	//@parm OUT: ptr to next font name in input buffer
								) const
{
	PARSEFONTNAME iRet = PFN_SUCCESS;

	Assert(pchBuf);
	Assert(pchBufMax);
	Assert(pchBufMax >= pchBuf);
	Assert(pszName);
	Assert(ppchBufNew);

	fSetCharSet = FALSE;
	*pszName = pchBuf;
	
	if(pchBuf > pchBufMax)
	{
		return PFN_EOF;
	}

	while(*pchBuf && *pchBuf != TEXT(',') && *pchBuf != chDelimiter)
	{
		pchBuf++;

		if(pchBuf > pchBufMax)
		{
			return PFN_EOF;
		}
	}

	TCHAR chTemp = *pchBuf;
	*pchBuf = TEXT('\0');
	RemoveAdditionalSpace(*pszName);

	if(chTemp == TEXT(','))
	{
		TCHAR *szCharSet = ++pchBuf;

		while(*pchBuf && *pchBuf != chDelimiter)
		{
			pchBuf++;

			if(pchBuf > pchBufMax)
			{
				return PFN_EOF;
			}
		}

		chTemp = *pchBuf;

		if(chTemp != chDelimiter)
		{
			goto UnexpectedChar;
		}

		*pchBuf = TEXT('\0');
		RemoveAdditionalSpace(szCharSet);

		bCharSet = 0;
		while(*szCharSet >= TEXT('0') && *szCharSet <= TEXT('9'))
		{
			bCharSet *= 10;
			bCharSet += *szCharSet++ - TEXT('0');
		}

		fSetCharSet = TRUE;
		// iRet = PFN_SUCCESS;	(done above)
	}
	else if(chTemp == chDelimiter)
	{
		// fSetCharSet = FALSE;	(done above)

⌨️ 快捷键说明

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