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

📄 text.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 TEXT.C -- CTxtPtr implementation |
 *	
 *	Authors: <nl>
 *		Original RichEdit code: David R. Fulmer <nl>
 *		Christian Fortini <nl>
 *		Murray Sargent <nl>
 *
 *	History: <nl>
 *		6/25/95		alexgo	cleanup and reorganization (use run pointers now)
 *
 */

#include "_common.h"
#include "_text.h"
#include "_edit.h"
#include "_antievt.h"
#include "_clasfyc.h"


ASSERTDATA

//-----------------------------Internal functions--------------------------------
// Text Block management
LOCAL void TxDivideInsertion(DWORD cch, DWORD ichBlock, DWORD cchAfter,
			DWORD *pcchFirst, DWORD *pcchLast);

#define IsSameNonFEClass(_c1, _c2)	(!(((_c1) ^ (_c2)) & WBF_CLASS))

#define IdeoKanaTypes (C3_HALFWIDTH | C3_FULLWIDTH | C3_KATAKANA | C3_HIRAGANA)
#define IdeoTypes	  (IdeoKanaTypes | C3_IDEOGRAPH)
#define IsIdeographic(_c1) ( 0 != (_c1 & (C3_KATAKANA | C3_HIRAGANA | C3_IDEOGRAPH)) )

/*
 *	IsSameClass(currType1, startType1, currType3, startType3 )
 *
 *	@func	Used to determine word breaks.
 *
 *	@comm	Ideographic chars are all considered to be unique, so that only
 *			one at a time is selected
 */
static BOOL IsSameClass(WORD currType1, WORD startType1,
						WORD currType3, WORD startType3 )
{
	BOOL	fIdeographic = IsIdeographic(currType3);

	// Do classifications for startType3 being ideographic
	if (IsIdeographic(startType3))
	{
		WORD	checkTypes  = (currType3 & IdeoTypes) ^ (startType3 & IdeoTypes);

		// We only get picky with non-ideographic Kana chars
		//  C3_HALFWIDTH | C3_FULLWIDTH | C3_KATAKANA | C3_HIRAGANA.
		return fIdeographic && (startType3 & IdeoKanaTypes) &&
			   (!checkTypes || checkTypes == C3_FULLWIDTH || checkTypes == C3_HIRAGANA || 
			   checkTypes == (C3_FULLWIDTH | C3_HIRAGANA));
	}	

	// Do classifications for nonideographic startType3
	return !fIdeographic && IsSameNonFEClass(currType1, startType1);
}

static ClassifyChar(TCHAR ch)
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "ClassifyChar");
	WORD wRes;

	if (IsKorean(ch))									// special Korean class
		return 0x0f;

	if (ch == WCH_EMBEDDING)							// Objects
		return 2 | WBF_BREAKAFTER;

	if (!W32->GetStringTypeEx(LOCALE_SYSTEM_DEFAULT, CT_CTYPE1, &ch, 1, &wRes))
	{
	    return 0;  //GetStringTYpe failed - nothing more to do
	}    

	if(wRes & C1_SPACE)
	{
		if(wRes & C1_BLANK)								// Only TAB, BLANK, and
		{												//  nobreak BLANK are here
			if(ch == 0x20)
				return 2 | WBF_BREAKLINE | WBF_ISWHITE;
			if(ch == TAB)
				return 3 | WBF_ISWHITE;
			return 2 | WBF_ISWHITE;
		}
		if(ch == CELL)
			return 3 | WBF_ISWHITE;
		return 4 | WBF_ISWHITE;
	}
	if(wRes & C1_PUNCT)
		return ch == '-' ? (1 | WBF_BREAKAFTER) : 1;
	return 0;
}

static void ClassifyChars(const TCHAR *pch, LONG cch, WORD *pwRes)
{ 
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "ClassifyChars");
	WORD	wRes;
	TCHAR	ch;

	if (!W32->GetStringTypeEx(LOCALE_SYSTEM_DEFAULT, CT_CTYPE1, pch, cch, pwRes))
	{
	    //since we don't return a value here, we need to make sure that pwRes is initialized
	    ZeroMemory(pwRes, cch);
	    return;
    }
    

	while(cch--)
	{
		wRes = *pwRes;
		ch = *pch++;
		
		if (IsKorean(ch))								
			wRes = 0x0f;								// special Korean class
		else if (ch == WCH_EMBEDDING)					// Objects
			wRes = 2 | WBF_BREAKAFTER;
		else if(wRes & C1_SPACE)
		{
			if (wRes & C1_BLANK)
			{
				wRes = 2 | WBF_ISWHITE;
				if(ch == 0x20)
					wRes = 2 | WBF_BREAKLINE | WBF_ISWHITE;
				if(ch == TAB)
					wRes = 3 | WBF_ISWHITE;
			}
			else
				wRes = 4 | WBF_ISWHITE;
		}
		else if(ch == CELL)
			wRes = 3 | WBF_ISWHITE;

		else if(wRes & C1_PUNCT)
			wRes = ch == '-' ? (1 | WBF_BREAKAFTER) : 1;

		else 
			wRes = 0;
		*pwRes++ = wRes;
	}
}

/*
 *	IsEOP(ch)
 *
 *	@func
 *		Used to determine if ch is an EOP char, i.e., CR, LF, VT, FF, PS, or
 *		LS (Unicode paragraph/line separator). This function (or its CR/LF
 *		subset) is often inlined, but is useful if speed isn't critical.
 *
 *	@rdesc
 *		TRUE if ch is an end-of-paragraph char
 */  
BOOL IsEOP(unsigned ch)
{
	return IN_RANGE(LF, ch, CR) || (ch | 1) == PS;
}

/*
 *	IsWhiteSpace(ch)
 *
 *	@func
 *		Used to determine if ch is an EOP char (see IsEOP() for definition),
 *		TAB or blank. This function is used in identifying sentence start
 *		and end.
 *
 *	@rdesc
 *		TRUE if ch is whitespace
 */  
BOOL IsWhiteSpace(unsigned ch)
{
	return ch == ' ' || IN_RANGE(CELL, ch, CR) || (ch | 1) == PS;
}

/*
 *	IsSentenceTerminator(ch)
 *
 *	@func
 *		Used to determine if ch is a standard sentence terminator character,
 *		namely, '?', '.', or '!'
 *
 *	@rdesc
 *		TRUE if ch is a question mark, period, or exclamation point.
 */  
BOOL IsSentenceTerminator(unsigned ch)
{
	return ch == '?' || ch == '.' || ch == '!';		// Std sentence delimiters
}


// ===========================  Invariant stuff  ==================================================

#define DEBUG_CLASSNAME CTxtPtr
#include "_invar.h"

// ===============================  CTxtPtr  ======================================================

#ifdef DEBUG

/*
 *	CTxtPtr::Invariant
 *
 *	@mfunc	invariant check
 */
BOOL CTxtPtr::Invariant( ) const
{
	static LONG	numTests = 0;
	numTests++;				// how many times we've been called.

	// make sure _cp is within range.
	Assert(_cp >= 0 );

	CRunPtrBase::Invariant();

	if( _prgRun )
	{
		// we use less than or equals here so that we can be an insertion
		// point at the *end* of the currently existing text (cpLim).
		Assert(_cp <= GetTextLength());

		// make sure all the blocks are consistent...
		((CTxtArray *)_prgRun)->Invariant();
	}

	Assert( _cp == CRunPtrBase::GetCp() );

	return TRUE;
}

/*
 *	CTxtPtr::MoveGapToEndOfBlock ()
 *	
 *	@mfunc
 *		Function to move buffer gap to current block end to aid in debugging
 */
void CTxtPtr::MoveGapToEndOfBlock () const
{
 	CTxtBlk *ptb = GetRun(0);
	ptb->MoveGap(ptb->_cch);				// Move gaps to end of cur block
}

#endif	// DEBUG


/*
 *	CTxtPtr::CTxtPtr(ped, cp)
 *
 *	@mfunc	constructor
 */
CTxtPtr::CTxtPtr (
	CTxtEdit *ped,		//@parm	Ptr to CTxtEdit instance
	DWORD cp)			//@parm cp to set the pointer to
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::CTxtPtr");

	_ped = ped;
	_cp = 0;
	SetRunArray((CRunArray *) &ped->GetTxtStory()->_TxtArray);
	_cp = BindToCp(cp);
}

/*
 *	CTxtPtr::CTxtPtr(&tp)
 *
 *	@mfunc	Copy Constructor
 */
CTxtPtr::CTxtPtr (
	const CTxtPtr &tp)
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::CTxtPtr");

	// copy all the values over
	*this = tp;
}	

/*
 *	CTxtPtr::GetTextLength()
 *	
 *	@mfunc
 *		Return count of characters in the story pointed to by this
 *		text ptr.  Includes the story's final CR in the count
 *
 *	@rdesc
 *		cch for the story pointed to by this text ptr
 *
 *	@devnote
 *		This method returns 0 if the text ptr is a zombie, a state
 *		identified by _ped = NULL.
 */
DWORD CTxtPtr::GetTextLength() const
{
	return _ped ? ((CTxtArray *)_prgRun)->_cchText : 0;
}

/*
 *	CTxtPtr::GetChar()
 *	
 *	@mfunc
 *		Return character at this text pointer, NULL if text pointer is at 
 *		end of text
 *
 *	@rdesc
 *		Character at this text ptr
 */
TCHAR CTxtPtr::GetChar()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetChar");

	LONG		 cchValid;
	const TCHAR *pch = GetPch(cchValid);

	return pch ? *pch : 0;
}  

/*
 *	CTxtPtr::GetPrevChar()
 *	
 *	@mfunc
 *		Return character just before this text pointer, NULL if text pointer 
 *		beginning of text
 *
 *	@rdesc
 *		Character just before this text ptr
 */
TCHAR CTxtPtr::GetPrevChar()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetPrevChar");

	LONG		 cchValid;
	const TCHAR *pch = GetPchReverse(cchValid);
       if (pch && (pch-1))
            return *(pch - 1);
       else
            return 0;
}  

/*
 *	CTxtPtr::GetPch(&cchValid)
 *	
 *	@mfunc
 *		return a character pointer to the text at this text pointer
 *
 *	@rdesc
 *		a pointer to an array of characters.  May be NULL.  If non-null,
 *		then cchValid is guaranteed to be at least 1
 */
const TCHAR * CTxtPtr::GetPch(
	LONG & 	cchValid)		//@parm	Count of characters for which the
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetPch");
							//		returned pointer is valid
	_TEST_INVARIANT_

	DWORD		ich = _ich;
	TCHAR *		pchBase;
	CTxtBlk *	ptb = _prgRun ? GetRun(0) : NULL;

	if( !ptb )
	{
		cchValid = 0;
		return NULL;
	}

	// if we're at the edge of a run, grab the next run or 
	// stay at the current run.

	if( _ich == ptb->_cch )
	{
		if( _iRun < Count() - 1 )
		{
			// set us to the next text block
			ptb = GetRun(1);
			ich = 0;
		}
		else
		{
			//we're at the very end of the text, just return NULL
			cchValid = 0;
			return NULL;
		}
	}

	AssertSz(CbOfCch(ich) <= ptb->_cbBlock,
		"CTxtPtr::GetPch(): _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 beyond the gap, then recompute pchBase
	// by adding in the size of the block.
	//
	// cchValid will then be the number of characters left in
	// the text block (or _cch - ich) 
  
	if(CbOfCch(ich) >= ptb->_ibGap)
	{
		pchBase += CchOfCb(ptb->_cbBlock) - ptb->_cch;
		cchValid = ptb->_cch - ich;
	}
	else
	{
		//we're valid until the buffer gap (or see below).
		cchValid = CchOfCb(ptb->_ibGap) - ich;
	}

	Assert(cchValid);
	return pchBase;
}

/*
 *	CTxtPtr::GetPchReverse(&cchValidReverse, pcchValid)
 *	
 *	@mfunc
 *		return a character pointer to the text at this text pointer
 *		adjusted so that there are some characters valid *behind* the
 *		pointer.
 *
 *	@rdesc
 *		a pointer to an array of characters.  May be NULL.  If non-null,
 *		then cchValidReverse is guaranteed to be at least 1
 */
const TCHAR * CTxtPtr::GetPchReverse(
	LONG & 	cchValidReverse,		//@parm	length for reverse 
	LONG *	pcchValid)				//@parm length forward
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtPtr::GetPchReverse");

	_TEST_INVARIANT_

	LONG		cchTemp;
	DWORD		ich = _ich;
	TCHAR *		pchBase;
	CTxtBlk *	ptb = GetRun(0);

	if( !ptb )
	{
		cchValidReverse = 0;
		return NULL;
	}

	// if we're at the edge of a run, grab the previous run or 
	// stay at the current run.

	if( !_ich )
	{
		if( _iRun )

⌨️ 快捷键说明

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