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

📄 cedtviewformat.cpp

📁 Crimson编辑器的英文版,完成从韩文版变成英文版的移植,并且附带可执行文件和注册表文件,无需原先的安装包,是改写编辑器的最理想选择.
💻 CPP
字号:
#include "stdafx.h"
#include "cedtHeader.h"


static FORMATEDWORDINFO _words[MAX_WORDS_COUNT+1];

// width setting global variables
static BOOL  _bFixedWidth;
static INT   _nSpaceWidth, _nTabWidth, _nTabMargin;
static INT   _nWrapWidth, _nIndentWidth, _nMinWidth;

// temporary global variables for format text
static BOOL  _bWordSplit; 
static INT   _nLeadingSpaceWidth;
static SHORT _sLineSplitIndex, _sWordIndex;

static UCHAR _cType, _cRange;
static SHORT _sIndex, _sLength;



static INT _GetLeadingSpaceWidth(CAnalyzedString & rLine, CDC * pDC) 
{
	SHORT i, sLength; INT nWidth, nPosition = 0;
	UCHAR cType;

	for(i = 0; i < rLine.m_sWordCount; i++) {
		ANALYZEDWORDINFO & rWordInfo = rLine.m_pWordInfo[i];
		cType = rWordInfo.m_cType; sLength = rWordInfo.m_sLength;

		if( cType == WT_TAB ) {
			nWidth = ((nPosition + _nSpaceWidth - _nTabMargin) / _nTabWidth + 1) * _nTabWidth - nPosition;
		} else if( cType == WT_SPACE ) {
			nWidth = _nSpaceWidth * sLength;
		} else break;

		nPosition += nWidth;
	}
	return nPosition;
}

static INT _GetWordWidth(LPCTSTR pWord, SHORT sLength, INT nPosition, UCHAR cType, CDC * pDC)
{
	INT nWidth; CSize size;

	if( cType == WT_TAB ) {
		nWidth = ((nPosition + _nSpaceWidth - _nTabMargin) / _nTabWidth + 1) * _nTabWidth - nPosition;
	} else if( cType == WT_SPACE ) {
		nWidth = _nSpaceWidth * sLength;
	} else if( _bFixedWidth ) {
		nWidth = _nSpaceWidth * sLength;
	} else {
		size = pDC->GetTextExtent(pWord, sLength);
		nWidth = (SHORT)size.cx;
	}
	return nWidth;
}

static SHORT _GetWordIndex(LPCTSTR pWord, SHORT sLength, INT nWidth, CDC * pDC)
{
	SHORT i, sIndex; CSize size;
	for(i = 0; i <= sLength; i++) {
		if( _bFixedWidth ) size.cx = _nSpaceWidth * i;
		else size = pDC->GetTextExtent(pWord, i);

		if( size.cx <= nWidth ) sIndex = i;
		else break;
	}
	return sIndex;
}


static void _WordFound(SHORT windex, UCHAR cType, UCHAR cRange, SHORT sIndex, SHORT sLength, INT nPosition, INT nWidth)
{
	_words[windex].m_cType = cType;
	_words[windex].m_cRange = cRange;
	_words[windex].m_sIndex = sIndex;
	_words[windex].m_sLength = sLength;
	_words[windex].m_nPosition = nPosition;
	_words[windex].m_nWidth = nWidth;
}

static void _FinishLine(SHORT wcount, SHORT sLineSplitIndex, CFormatedString & rFmtLine, CAnalyzedString & rLine)
{
	delete [] rFmtLine.m_pWordInfo;
	rFmtLine.m_pWordInfo = new FORMATEDWORDINFO[wcount];
	rFmtLine.m_sWordCount = wcount;
	memcpy(rFmtLine.m_pWordInfo, _words, wcount * sizeof(FORMATEDWORDINFO));

	rFmtLine.m_pString = (LPCTSTR)rLine;
	rFmtLine.m_sLineSplitIndex = sLineSplitIndex;
	rFmtLine.m_sInfoFlags = rLine.m_sInfoFlags;
}


static BOOL _FormatLineWrap(CFormatedString & rFmtLine, CAnalyzedString & rLine, CDC * pDC)
{
	
	SHORT i, wcount, sIndex, sLength, sSplit; 
	INT nPosition, nWidth; UCHAR cType, cRange;

	_nLeadingSpaceWidth = _GetLeadingSpaceWidth(rLine, pDC);
	_sLineSplitIndex = 0;

	wcount = nPosition = 0;
	for(i = 0; i < rLine.m_sWordCount; i++) {
		ANALYZEDWORDINFO & rWord = rLine.m_pWordInfo[i];
		cType = rWord.m_cType; cRange = rWord.m_cRange;
		sIndex = rWord.m_sIndex; sLength = rWord.m_sLength;

		nWidth = _GetWordWidth((LPCTSTR)rLine + sIndex, sLength, nPosition, cType, pDC);

		if( _nWrapWidth <= _nLeadingSpaceWidth + _nIndentWidth + _nMinWidth ) {
			// not enough space - add in the same line
			_WordFound(wcount++, cType, cRange, sIndex, sLength, nPosition, nWidth);
			nPosition += nWidth; _bWordSplit = FALSE;
		} else if( nPosition + nWidth <= _nWrapWidth || (cType == WT_RETURN || cType == WT_TAB || cType == WT_SPACE) ) {
			// add in the same line
			_WordFound(wcount++, cType, cRange, sIndex, sLength, nPosition, nWidth);
			nPosition += nWidth; _bWordSplit = FALSE;
		} else if( _nLeadingSpaceWidth + _nIndentWidth + nWidth <= _nWrapWidth ) {
			// go next line
			_WordFound(wcount++, WT_LINEFEED, RT_GLOBAL, sIndex, 0, nPosition, 0);
			_bWordSplit = FALSE; _sWordIndex = i; break;
		} else {
			// split word - go next line
			sSplit = _GetWordIndex((LPCTSTR)rLine + sIndex, sLength, _nWrapWidth - nPosition, pDC);
			nWidth = _GetWordWidth((LPCTSTR)rLine + sIndex, sSplit, nPosition, cType, pDC);

			_WordFound(wcount++, cType, cRange, sIndex, sSplit, nPosition, nWidth);
			sIndex += sSplit; sLength -= sSplit; nPosition += nWidth;

			_WordFound(wcount++, WT_LINEFEED, RT_GLOBAL, sIndex, 0, nPosition, 0);
			_cType = cType; _cRange = cRange; _sIndex = sIndex; _sLength = sLength;
			_bWordSplit = TRUE; _sWordIndex = i; break;
		}
	}

	_FinishLine(wcount, _sLineSplitIndex++, rFmtLine, rLine);
	return ( i < rLine.m_sWordCount ) ? TRUE : FALSE;
}


static BOOL _FormatLineWrapContinue(CFormatedString & rFmtLine, CAnalyzedString & rLine, CDC * pDC)
{
	SHORT i, wcount, sIndex, sLength, sSplit;
	INT nPosition, nWidth; UCHAR cType, cRange;

	wcount = 0; nPosition = _nLeadingSpaceWidth + _nIndentWidth;
	for(i = _sWordIndex; i < rLine.m_sWordCount; i++) {
		if( _bWordSplit ) {
			cType = _cType; cRange = _cRange; 
			sIndex = _sIndex; sLength = _sLength;
		} else {
			ANALYZEDWORDINFO & rWord = rLine.m_pWordInfo[i];
			cType = rWord.m_cType; cRange = rWord.m_cRange;
			sIndex = rWord.m_sIndex; sLength = rWord.m_sLength;
		}

		nWidth = _GetWordWidth((LPCTSTR)rLine + sIndex, sLength, nPosition, cType, pDC);

		if( nPosition + nWidth <= _nWrapWidth || (cType == WT_RETURN || cType == WT_TAB || cType == WT_SPACE) ) {
			// add in the same line
			_WordFound(wcount++, cType, cRange, sIndex, sLength, nPosition, nWidth);
			nPosition += nWidth; _bWordSplit = FALSE;
		} else if( _nLeadingSpaceWidth + _nIndentWidth + nWidth <= _nWrapWidth ) {
			// go next line
			_WordFound(wcount++, WT_LINEFEED, RT_GLOBAL, sIndex, 0, nPosition, 0);
			_bWordSplit = FALSE; _sWordIndex = i; break;
		} else {
			// split word - go next line
			sSplit = _GetWordIndex((LPCTSTR)rLine + sIndex, sLength, _nWrapWidth - nPosition, pDC);
			nWidth = _GetWordWidth((LPCTSTR)rLine + sIndex, sSplit, nPosition, cType, pDC);

			_WordFound(wcount++, cType, cRange, sIndex, sSplit, nPosition, nWidth);
			sIndex += sSplit; sLength -= sSplit; nPosition += nWidth;

			_WordFound(wcount++, WT_LINEFEED, RT_GLOBAL, sIndex, 0, nPosition, 0);
			_cType = cType; _cRange = cRange; _sIndex = sIndex; _sLength = sLength;
			_bWordSplit = TRUE; _sWordIndex = i; break;
		}
	}

	_FinishLine(wcount, _sLineSplitIndex++, rFmtLine, rLine);
	return ( i < rLine.m_sWordCount ) ? TRUE : FALSE;
}


static BOOL _FormatLineNoWrap(CFormatedString & rFmtLine, CAnalyzedString & rLine, CDC * pDC)
{
	SHORT i, wcount, sIndex, sLength;
	INT nPosition, nWidth; UCHAR cType, cRange;

	wcount = nPosition = 0;
	for(i = 0; i < rLine.m_sWordCount; i++) {
		ANALYZEDWORDINFO & rWord = rLine.m_pWordInfo[i];
		cType = rWord.m_cType; cRange = rWord.m_cRange;
		sIndex = rWord.m_sIndex; sLength = rWord.m_sLength;

		nWidth = _GetWordWidth((LPCTSTR)rLine + sIndex, sLength, nPosition, cType, pDC);

		_WordFound(wcount++, cType, cRange, sIndex, sLength, nPosition, nWidth);
		nPosition += nWidth;
	}

	_FinishLine(wcount, 0, rFmtLine, rLine);
	return FALSE;
}


void CCedtView::FormatScreenText() 
{
	CCedtDoc * pDoc = (CCedtDoc *)GetDocument();
	INT nLineCount = pDoc->GetLineCount();

	m_clsFormatedScreenText.RemoveAll(); CFormatedString dummyLine;
	for(INT i = 0; i < nLineCount; i++) m_clsFormatedScreenText.AddTail( dummyLine );

	FormatScreenText(0, nLineCount);
}


void CCedtView::FormatScreenText(INT nIndex, INT nCount) 
{
	CRect rect; GetClientRect( & rect );
	INT nLeftMargin = GetLeftMargin();
	INT nAveCharWidth = GetAveCharWidth();
	INT nMaxCharWidth = GetMaxCharWidth();

	// save width setting to global variables
	_bFixedWidth = IsUsingFixedPitchFont();
	_nSpaceWidth = GetSpaceWidth();
	_nTabWidth = m_nTabSize * _nSpaceWidth;
	_nTabMargin = 1;

	// save wrap setting to gloabl variables
	if( m_nFixedWrapWidth ) _nWrapWidth = m_nFixedWrapWidth * nAveCharWidth;
	else _nWrapWidth = rect.Width() - nLeftMargin - nMaxCharWidth;
	_nIndentWidth = m_nWrapIndentation * _nSpaceWidth;
	_nMinWidth = 8 * nAveCharWidth;


	CCedtDoc * pDoc = (CCedtDoc *)GetDocument(); ASSERT( pDoc );
	CMainFrame * pMainFrame = (CMainFrame *)AfxGetMainWnd(); ASSERT( pMainFrame );
	INT nProcess = 0; CWaitCursor * pWait = NULL;

	if( nCount > 1000 ) {
		pWait = new CWaitCursor;
		pMainFrame->BeginProgress("Formatting...");
	}

	POSITION po1 = pDoc->m_clsAnalyzedText.FindIndex(nIndex);
	POSITION po2 = FindScreenTextIndex(nIndex);
	if( m_bLocalWordWrap ) {
		while( po1 && nProcess < nCount ) {
			CAnalyzedString & rLine = pDoc->m_clsAnalyzedText.GetNext(po1); FlattenScreenTextAt(po2);
			BOOL bContinue = _FormatLineWrap( m_clsFormatedScreenText.GetAt(po2), rLine, & m_dcScreen );
			while( bContinue ) {
				CFormatedString dummyLine; po2 = m_clsFormatedScreenText.InsertAfter(po2, dummyLine);
				bContinue = _FormatLineWrapContinue( m_clsFormatedScreenText.GetAt(po2), rLine, & m_dcScreen );
			}
			m_clsFormatedScreenText.GetNext(po2);

			if( nCount > 1000 && ! (nProcess % 20) ) pMainFrame->SetProgress( 100 * nProcess / nCount );
			nProcess++;
		}
	} else {
		while( po1 && nProcess < nCount ) {
			CAnalyzedString & rLine = pDoc->m_clsAnalyzedText.GetNext(po1); FlattenScreenTextAt(po2);
			_FormatLineNoWrap( m_clsFormatedScreenText.GetNext(po2), rLine, & m_dcScreen );

			if( nCount > 1000 && ! (nProcess % 20) ) pMainFrame->SetProgress( 100 * nProcess / nCount );
			nProcess++;
		}
	}	

	if( nCount > 1000 ) {
		delete pWait;
		pMainFrame->EndProgress();
	}
}


void CCedtView::FormatPrintText(CDC * pDC, RECT rectDraw)
{
	CCedtDoc * pDoc = (CCedtDoc *)GetDocument();
	FormatPrintText(pDC, rectDraw, 0, pDoc->GetLineCount());
}


void CCedtView::FormatPrintText(CDC * pDC, RECT rectDraw, INT nIdxY, INT nCount)
{
	CRect rect( rectDraw );
	INT nLeftMargin = GetLeftMargin( pDC );
	INT nAveCharWidth = GetAveCharWidth( pDC );
	INT nMaxCharWidth = GetMaxCharWidth( pDC );

	// save width setting to global variables
	_bFixedWidth = IsUsingFixedPitchFont( pDC );
	_nSpaceWidth = GetSpaceWidth( pDC );
	_nTabWidth = m_nTabSize * _nSpaceWidth;
	_nTabMargin = _MY_MAX(_nSpaceWidth / 10, 1);

	// save wrap setting to gloabl variables
	_nWrapWidth = rect.Width() - nLeftMargin - nMaxCharWidth;
	_nIndentWidth = m_nWrapIndentation * _nSpaceWidth;
	_nMinWidth = 8 * nAveCharWidth;


	m_clsFormatedPrintText.RemoveAll(); CFormatedString dummyLine;
	for(INT i = 0; i < nCount; i++) m_clsFormatedPrintText.AddTail( dummyLine );

	CCedtDoc * pDoc = (CCedtDoc *)GetDocument(); ASSERT( pDoc );
	CMainFrame * pMainFrame = (CMainFrame *)AfxGetMainWnd(); ASSERT( pMainFrame );
	INT nProcess = 0; CWaitCursor * pWait = NULL;

	pWait = new CWaitCursor;
	if( nCount > 100 ) pMainFrame->BeginProgress("Formatting...");

	POSITION po1 = pDoc->m_clsAnalyzedText.FindIndex(nIdxY);
	POSITION po2 = m_clsFormatedPrintText.GetHeadPosition();
	while( po1 && nProcess < nCount ) {
		CAnalyzedString & rLine = pDoc->m_clsAnalyzedText.GetNext(po1);
		BOOL bContinue = _FormatLineWrap( m_clsFormatedPrintText.GetAt(po2), rLine, pDC );
		while( bContinue ) {
			po2 = m_clsFormatedPrintText.InsertAfter(po2, dummyLine);
			bContinue = _FormatLineWrapContinue( m_clsFormatedPrintText.GetAt(po2), rLine, pDC );
		}
		m_clsFormatedPrintText.GetNext(po2);

		if( nCount > 100 && ! (nProcess % 2) ) pMainFrame->SetProgress( 100 * nProcess / nCount );
		nProcess++;
	}

	delete pWait;
	if( nCount > 100 ) pMainFrame->EndProgress();
}


void CCedtView::RemoveScreenText(INT nIndex, INT nCount)
{
	POSITION posRemove = FindScreenTextIndex( nIndex );
	while( nCount-- ) posRemove = RemoveScreenTextAt( posRemove );
}

void CCedtView::InsertScreenText(INT nIndex, INT nCount)
{
	CFormatedString dummyLine;
	POSITION posInsert = (nIndex < 0) ? NULL : FindScreenTextIndex( nIndex );

	if( posInsert ) while( nCount-- ) m_clsFormatedScreenText.InsertAfter( posInsert, dummyLine );
	else while( nCount-- ) m_clsFormatedScreenText.AddHead( dummyLine );
}


INT CCedtView::GetWordWidth(LPCTSTR lpWord, SHORT siLength, INT nPosition, UCHAR ucType, CDC * pDC)
{
	// save width setting to global variables
	_bFixedWidth = IsUsingFixedPitchFont( pDC );
	_nSpaceWidth = GetSpaceWidth( pDC );
	_nTabWidth = m_nTabSize * _nSpaceWidth;
	_nTabMargin = _MY_MAX(_nSpaceWidth / 10, 1);

	if( pDC ) return _GetWordWidth(lpWord, siLength, nPosition, ucType, pDC);
	else return _GetWordWidth(lpWord, siLength, nPosition, ucType, & m_dcScreen);
}

SHORT CCedtView::GetWordIndex(LPCTSTR lpWord, SHORT siLength, INT nWidth, CDC * pDC)
{
	// save width setting to global variables
	_bFixedWidth = IsUsingFixedPitchFont( pDC );
	_nSpaceWidth = GetSpaceWidth( pDC );
	_nTabWidth = m_nTabSize * _nSpaceWidth;
	_nTabMargin = _MY_MAX(_nSpaceWidth / 10, 1);

	if( pDC ) return _GetWordIndex(lpWord, siLength, nWidth, pDC);
	else return _GetWordIndex(lpWord, siLength, nWidth, & m_dcScreen);
}


POSITION CCedtView::FindScreenTextIndex(INT nIndex)
{
	INT nParaCount = 0;
	POSITION posFound, pos = m_clsFormatedScreenText.GetHeadPosition();
	while( pos ) {
		posFound = pos;
		CFormatedString & rLine = m_clsFormatedScreenText.GetNext( pos );
		if( rLine.m_sLineSplitIndex == 0 ) nParaCount++;
		if( nParaCount-1 == nIndex ) break;
	}
	return posFound;
}

POSITION CCedtView::FlattenScreenTextAt(POSITION pos)
{
	INT nParaCount = 0;
	POSITION posFlatten;
	while( pos ) {
		posFlatten = pos;
		CFormatedString & rLine = m_clsFormatedScreenText.GetNext( pos );
		if( rLine.m_sLineSplitIndex == 0 ) nParaCount++;
		if( nParaCount-1 == 0 ) {
			if( rLine.m_sLineSplitIndex ) m_clsFormatedScreenText.RemoveAt( posFlatten );
		} else break;
	}
	return posFlatten;
}

POSITION CCedtView::RemoveScreenTextAt(POSITION pos)
{
	INT nParaCount = 0;
	POSITION posRemove;
	while( pos ) {
		posRemove = pos;
		CFormatedString & rLine = m_clsFormatedScreenText.GetNext( pos );
		if( rLine.m_sLineSplitIndex == 0 ) nParaCount++;
		if( nParaCount-1 == 0 ) m_clsFormatedScreenText.RemoveAt( posRemove );
		else break;
	}
	return posRemove;
}

⌨️ 快捷键说明

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