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

📄 text.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
			// set us to the next text block
			ptb = GetRun(-1);
			ich = ptb->_cch;
		}
		else
		{
			//we're at the very beginning of the text, just return NULL
			cchValidReverse = 0;
			return NULL;
		}
	}

	AssertSz(CbOfCch(ich) <= ptb->_cbBlock,
		"CTxtPtr::GetPchReverse(): _ich bigger than block");

	pchBase = ptb->_pch + ich;

	// Check to see if we need to skip over gap.  Recall that
	// the game may come anywhere in the middle of a block,
	// so if the current ich (note, no underscore, we want 
	// the active ich) is at least one char past the gap, then recompute
	// pchBase by adding the size of the gap (so that it's after
	// the gap).  This differs from GetPch(), which works forward and
	// wants pchBase to include the gap size if ich is at the gap, let
	// alone one or more chars past it.
	//
	// Also figure out the count of valid characters.  It's
	// either the count of characters from the beginning of the 
	// text block, i.e. ich, or the count of characters from the
	// end of the buffer gap.

	cchValidReverse = ich;					// Default for ich <= gap offset
	cchTemp = ich - CchOfCb(ptb->_ibGap);	// Calculate displacement
	if(cchTemp > 0)							// Positive: pchBase is after gap
	{
		cchValidReverse = cchTemp;
		pchBase += CchOfCb(ptb->_cbBlock) - ptb->_cch;	// Add in gap size
	}
	if ( pcchValid )						// if client needs forward length
	{
		if ( cchTemp > 0 )
			cchTemp = ich - ptb->_cch;
		else
			cchTemp = -cchTemp;

		*pcchValid = cchTemp;
	}

	Assert(cchValidReverse);

	return pchBase;
}

/*
 *	CTxtPtr::BindToCp(cp)
 *
 *	@mfunc
 *		set cached _cp = cp (or nearest valid value)
 *
 *	@rdesc
 *		_cp actually set
 *
 *	@comm
 *		This method overrides CRunPtrBase::BindToCp to keep _cp up to date
 *		correctly.
 *
 *	@devnote
 *		Do *not* call this method when high performance is needed; use
 *		AdvanceCp() instead, which advances from 0 or from the cached
 *		_cp, depending on which is closer.
 */
DWORD CTxtPtr::BindToCp(
	DWORD	cp)			//@parm	char position to bind to
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::BindToCp");

	_cp = CRunPtrBase::BindToCp(cp);

	// We want to be able to use this routine to fix up things so we don't
	// check invariants on entry.
	_TEST_INVARIANT_
	return _cp;
}


/*
 *	CTxtPtr::SetCp(cp)
 *
 *	@mfunc
 *		'efficiently' sets cp by advancing from current position or from 0,
 *		depending on which is closer
 *
 *	@rdesc
 *		cp actually set to
 */
DWORD CTxtPtr::SetCp(
	DWORD	cp)		//@parm char position to set to
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::SetCp");

	AdvanceCp(cp - _cp);
	return _cp;
}

/*
 *	CTxtPtr::AdvanceCp(cch)
 *
 *	@mfunc
 *		Advance cp by cch characters
 *
 *	@rdesc
 *		Actual number of characters advanced by
 *
 *	@comm
 *		We override CRunPtrBase::AdvanceCp so that the cached _cp value
 *		can be correctly updated and so that the advance can be made
 *		from the cached _cp or from 0, depending on which is closer.
 *
 *	@devnote
 *		It's also easy to bind at the end of the story. So an improved
 *		optimization would bind there if 2*(_cp + cch) > _cp + text length.
 */
LONG CTxtPtr::AdvanceCp(
	LONG cch)			// @parm count of chars to advance by
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::AdvanceCp");

	if(!IsValid())							// No runs yet, so don't go
		return 0;							//  anywhere

	const LONG	cpSave = _cp;				// Save entry _cp
	LONG		cp = cpSave + cch;			// Requested target cp (maybe < 0)

	if(cp < cpSave/2)						// Closer to 0 than cached cp
	{
		cp = max(cp, 0);					// Don't undershoot
		_cp = CRunPtrBase::BindToCp(cp);
	}
	else
		_cp += CRunPtrBase::AdvanceCp(cch);	//  exist

	// NB! the invariant check needs to come at the end; we may be
	// moving 'this' text pointer in order to make it valid again
	// (for the floating range mechanism).

	_TEST_INVARIANT_
	return _cp - cpSave;					// cch this CTxtPtr moved
}

/*
 *	CTxtPtr::GetText(cch, pch)
 *	
 *	@mfunc
 *		get a range of cch characters starting at this text ptr. A literal
 *		copy is made, i.e., with no CR -> CRLF and WCH_EMBEDDING -> ' '
 *		translations.  For these translations, see CTxtPtr::GetPlainText()
 *	
 *	@rdesc
 *		count of characters actually copied
 *
 *  @comm
 *		Doesn't change this text ptr
 */
LONG CTxtPtr::GetText(
	LONG	cch, 			//@parm Count of characters to get
	TCHAR *	pch)			//@parm Buffer to copy the text into
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetText");

	LONG cchSave = cch;
	LONG cchValid;
	const TCHAR *pchRead;
	CTxtPtr tp(*this);

	_TEST_INVARIANT_

	// Use tp to read valid blocks of text until all the requested
	// text is read or until the end of story is reached.
	while( cch )
	{
		pchRead = tp.GetPch(cchValid);
		if(!pchRead)					// No more text
			break;

		cchValid = min(cchValid, cch);
		CopyMemory(pch, pchRead, cchValid*sizeof(TCHAR));
		pch += cchValid;
		cch -= cchValid;
		tp.AdvanceCp(cchValid);
	}
	return cchSave - cch;
}

/*
 *	CTxtPtr::GetPlainText(cchBuff, pch, cpMost, fTextize)
 *	
 *	@mfunc
 *		Copy up to cchBuff characters or up to cpMost, whichever comes
 *		first, translating lone CRs into CRLFs.  Move this text ptr just
 *		past the last character processed.  If fTextize, copy up to but
 *		not including the first WCH_EMBEDDING char. If not fTextize, 
 *		replace	WCH_EMBEDDING by a blank since RichEdit 1.0 does.
 *	
 *	@rdesc
 *		Count of characters copied
 *
 *  @comm
 *		An important feature is that this text ptr is moved just past the
 *		last char copied.  In this way, the caller can conveniently read
 *		out plain text in bufferfuls of up to cch chars, which is useful for
 *		stream I/O.  This routine won't copy the final CR even if cpMost
 *		is beyond it.
 */
LONG CTxtPtr::GetPlainText(
	LONG	cchBuff,		//@parm Buffer cch
	TCHAR *	pch,			//@parm Buffer to copy text into
	LONG	cpMost,			//@parm Largest cp to get
	BOOL	fTextize)		//@parm True if break on WCH_EMBEDDING
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetPlainText");

	LONG		 cch = cchBuff;				// Countdown counter
	LONG		 cchValid;					// Valid ptr cch
	LONG		 cchT;						// Temporary cch
	unsigned	 ch;						// Current char
	const TCHAR *pchRead;					// Backing-store ptr

	_TEST_INVARIANT_

	AdjustCpCRLF();							// Be sure we start on an EOP bdy

	LONG cchText = _ped->GetAdjustedTextLength();
	cpMost = min(cpMost, cchText);			// Don't write final CR
	if((LONG)GetCp() >= cpMost)
		return 0;

	while(cch > 0)							// While room in buffer
	{
		if(!(pchRead = GetPch(cchValid)))	// No more chars available
			break;							//  so we're out of here
		
		cchT = GetCp() + cchValid - cpMost;
		if(cchT > 0)						// Don't overshoot
		{
			cchValid -= cchT;
			if(cchValid <= 0)
				break;						// Nothing left before cpMost
		}

		for(cchT = 0; cch > 0 && cchT < cchValid; cchT++, cch--)
		{
			ch = *pch++ = *pchRead++;		// Copy next char (but don't
			if(IsASCIIEOP(ch))				//  count it yet)
			{
				AdvanceCp(cchT);			// Move up to CR
				if(cch < 2)					// No room for LF, so don't				
					goto done;				//  count CR either
											// Bypass EOP w/o worrying about
				cchT = AdvanceCpCRLF();		//  buffer gaps and blocks
				if(cchT > 2)				// Translate CRCRLF to ' '
				{							// Usually copied count exceeds
					Assert(cchT == 3);		//  internal count, but CRCRLFs
					*(pch - 1) = ' ';		//  reduce the relative increase:
				}							//  NB: error for EM_GETTEXTLENGTHEX
				else						// CRLF or lone CR
				{							// Store LF in both cases for
					*(pch - 1) = CR;		// Be sure it's a CR not a VT,
#ifndef MACPORT								//  FF, or lone LF
					*pch++ = LF;			// Windows. No LF for Mac
					cch--;					// One less for target buffer
#endif
				}
				cch--;						// CR (or ' ') copied
				cchT = 0;					// Don't AdvanceCp() more below
				break;						// Go get new pchRead & cchValid
			}
			else if(ch == WCH_EMBEDDING)	// Object lives here
			{
				if(fTextize)				// Break on WCH_EMBEDDING
				{
					AdvanceCp(cchT);		// Move this text ptr up to
					goto done;				//  WCH_EMBEDDING and return
				}
				*(pch - 1) = ' ';			// Replace embedding char by ' '
			}								//  since RichEdit 1.0 does
#ifdef PWD_JUPITER
            else if(ch == CELL)
            {
                // GuyBark Jupiter: We're writing out plain text here, so DON'T write
                // out RichEdit's own value for cell delimiters in tables. Instead
                // just write out a tab. This allows rows to be pasted into PExcel.
                *(pch - 1) = TAB;
            }
            // GuyBark JupiterJ 49481: J users do not want this action...
            // ARULM: Globalize: This is just plain weird, but the Japanese dont want 
            // this conversion to happen on Japanese machines. Whatever...
            else if((ch == LDBLQUOTE || ch == RDBLQUOTE) && !g_fHasJapanSupport)
            {
                // Left and right dbl quotes have code points in the 1252 code page.
                // This means unless we take action here, we output these left and
                // right characters in the text file. This is fine when re-opened in
                // PWord or Word97. But if the text file is opened in Notepage, it 
                // simply displays the square blocks for these extended characters.
                // That's not what we want, so always output the straight dbl quotes
                // for these characters when saving as text. This mimics Word97.
                *(pch - 1) = '"';
            }
            else if((ch == LQUOTE || ch == RQUOTE) && !g_fHasJapanSupport)
            {
                // The above also applies to left and right single quotes.
                *(pch - 1) = '\'';
            }
			// #endif // !FAREAST
            else if(ch == PWD_CRLFINCELL)
            {
                // We've hit the special character used to represent CRLF in 
                // table cells. Just is always followed by another space. This
                // isn't what Word97 does, (it starts a new line here), but who cares?
                *(pch - 1) = ' ';
            }

#endif // PWD_JUPITER
		}
		AdvanceCp(cchT);
	}

done:
	return cchBuff - cch;
}

/*
 *	CTxtPtr::AdvanceCpCRLF()
 *	
 *	@mfunc
 *		Advance text pointer by one character, safely advancing
 *		over CRLF, CRCRLF, and UTF-16 combinations
 *	
 *	@rdesc
 *		Number of characters text pointer has been moved by
 *
 *	@future
 *		Advance over Unicode combining marks
 */
LONG CTxtPtr::AdvanceCpCRLF()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::AdvanceCpCRLF");

	_TEST_INVARIANT_

	DWORD	cpSave	= _cp;
	TCHAR	ch		= GetChar();		// Char on entry
	TCHAR	ch1		= NextChar();		// Advance to and get next char
	BOOL	fTwoCRs = FALSE;

	if(ch == CR)
	{
		if(ch1 == CR && _cp < GetTextLength()) 
		{
			fTwoCRs = TRUE;				// Need at least 3 chars to
			ch1 = NextChar();			//  have CRCRLF at end
		}
		if(ch1 == LF)
			AdvanceCp(1);				// Bypass CRLF
		else if(fTwoCRs)
			AdvanceCp(-1);				// Only bypass one CR of two

		AssertSz(_ped->Get10Mode() || _cp == cpSave + 1,
			"CTxtPtr::AdvanceCpCRLF: EOP isn't a single char");
	}

//	To support UTF-16, include the following code
//	if ((ch & UTF16) == UTF16_TRAIL)	// Landed on UTF-16 trail word
//		AdvanceCp(1);					// Bypass UTF-16 trail word

	return _cp - cpSave;				// # chars bypassed
}

/*
 *	CTxtPtr::NextChar()
 *	
 *	@mfunc
 *		Increment this text ptr and return char it points at
 *	
 *	@rdesc
 *		Next char
 */
TCHAR CTxtPtr::NextChar()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::NextChar");

	_TEST_INVARIANT_

 	AdvanceCp(1);
	return GetChar();
}

/*
 *	CTxtPtr::PrevChar()
 *	
 *	@mfunc
 *		Decrement this text ptr and return char it points at
 *	
 *	@rdesc
 *		Previous char
 */
TCHAR CTxtPtr::PrevChar()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::PrevChar");

	_TEST_INVARIANT_

	return AdvanceCp(-1) ? GetChar() : 0;
}

/*
 *	CTxtPtr::BackupCpCRLF()
 *	
 *	@mfunc
 *		Backup text pointer by one character, safely backing up
 *		over CRLF, CRCRLF, and UTF-16 combinations
 *	
 *	@rdesc
 *		Number of characters text pointer has been moved by
 *
 *	@future
 *		Backup over Unicode combining marks
 */
LONG CTxtPtr::BackupCpCRLF()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::BackupCpCRLF");

	_TEST_INVARIANT_

	DWORD cpSave = _cp;
	TCHAR ch	 = PrevChar();			// Advance to and get previous char

	if (ch == LF &&					 	// Try to back up 1 char in any case
		(_cp && PrevChar() != CR ||		// If LF, does prev char = CR?
		 _cp && PrevChar() != CR))		// If so, does its prev char = CR?
	{									//  (CRLF at BOD checks CR twice; OK)
		AdvanceCp(1);					// Backed up too far
	}
//	To support UTF-16, include the following code
//	if ((ch & UTF16) == UTF16_TRAIL)	// Landed on UTF-16 trail word
//		AdvanceCp(-1);					// Backup to UTF-16 lead word

	return _cp - cpSave;				// - # chars this CTxtPtr moved
}

/*
 *	CTxtPtr::AdjustCpCRLF()
 *	
 *	@mfunc
 *		Adjust the position of this text pointer to the beginning of a CRLF,
 *		CRCRLF, or UTF-16 combination if it is in the middle of such a
 *		combination
 *	
 *	@rdesc
 *		Number of characters text pointer has been moved by
 *
 *	@future
 *		Adjust to beginning of sequence containing Unicode combining marks
 */
LONG CTxtPtr::AdjustCpCRLF()
{

⌨️ 快捷键说明

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