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

📄 clayoutmgr.cpp

📁 日本的开源编辑器源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//	$Id: CLayoutMgr.cpp,v 1.32 2004/12/23 09:27:15 genta Exp $
/*!	@file
	@brief テキストのレイアウト情報管理

	@author Norio Nakatani
	$Revision: 1.32 $
*/
/*
	Copyright (C) 1998-2001, Norio Nakatani
	Copyright (C) 2002, MIK

	This source code is designed for sakura editor.
	Please contact the copyright holder to use this code for other purpose.
*/
#include "CLayoutMgr.h"

/*** for TRACE()****
#include <afx.h>
***/
#include "charcode.h"
#include "debug.h"
#include <commctrl.h>
#include "CRunningTimer.h"
#include "CLayout.h"/// 2002/2/10 aroka
#include "CDocLine.h"/// 2002/2/10 aroka
#include "CDocLineMgr.h"/// 2002/2/10 aroka
#include "CMemory.h"/// 2002/2/10 aroka
#include "etc_uty.h" // Oct. 5, 2002 genta





/*
|| コンストラクタ
*/
CLayoutMgr::CLayoutMgr()
: m_cLineComment(), m_cBlockComment(),
	//	2004.04.03 Moca
	//	画面折り返し幅がTAB幅以下にならないことを初期値でも保証する
	m_nMaxLineSize( 10 ),
	//	Nov. 16, 2002 メンバー関数ポインタにはクラス名が必要
	getIndentOffset( &CLayoutMgr::getIndentOffset_Normal )	//	Oct. 1, 2002 genta
{
	m_pcDocLineMgr = NULL;
	m_bWordWrap = TRUE;		/* 英文ワードラップをする */
	m_nTabSpace = 8;		/* TAB文字スペース */
	m_nStringType = 0;		/* 文字列区切り記号エスケープ方法 0=[\"][\'] 1=[""][''] */
	m_bKinsokuHead = FALSE;		/* 行頭禁則 */	//@@@ 2002.04.08 MIK
	m_bKinsokuTail = FALSE;		/* 行末禁則 */	//@@@ 2002.04.08 MIK
	m_bKinsokuRet  = FALSE;		/* 改行文字をぶら下げる */	//@@@ 2002.04.13 MIK
	m_bKinsokuKuto = FALSE;		/* 句読点をぶら下げる */	//@@@ 2002.04.17 MIK
	m_pszKinsokuHead_1 = NULL;	/* 行頭禁則 */	//@@@ 2002.04.08 MIK
	m_pszKinsokuHead_2 = NULL;	/* 行頭禁則 */	//@@@ 2002.04.08 MIK
	m_pszKinsokuTail_1 = NULL;	/* 行末禁則 */	//@@@ 2002.04.08 MIK
	m_pszKinsokuTail_2 = NULL;	/* 行頭禁則 */	//@@@ 2002.04.08 MIK
	m_pszKinsokuKuto_1 = NULL;	/* 句読点ぶらさげ */	//@@@ 2002.04.17 MIK
	m_pszKinsokuKuto_2 = NULL;	/* 句読点ぶらさげ */	//@@@ 2002.04.17 MIK

	Init();
	return;
}


/*
|| デストラクタ
*/
CLayoutMgr::~CLayoutMgr()
{
	Empty();

	if( NULL != m_pszKinsokuHead_1 ){	/* 行頭禁則 */	//@@@ 2002.04.08 MIK
		delete [] m_pszKinsokuHead_1;
		m_pszKinsokuHead_1 = NULL;
	}
	if( NULL != m_pszKinsokuHead_2 ){	/* 行頭禁則 */	//@@@ 2002.04.08 MIK
		delete [] m_pszKinsokuHead_2;
		m_pszKinsokuHead_2 = NULL;
	}
	if( NULL != m_pszKinsokuTail_1 ){	/* 行末禁則 */	//@@@ 2002.04.08 MIK
		delete [] m_pszKinsokuTail_1;
		m_pszKinsokuTail_1 = NULL;
	}
	if( NULL != m_pszKinsokuTail_2 ){	/* 行末禁則 */	//@@@ 2002.04.08 MIK
		delete [] m_pszKinsokuTail_2;
		m_pszKinsokuTail_2 = NULL;
	}
	if( NULL != m_pszKinsokuKuto_1 ){	/* 句読点ぶらさげ */	//@@@ 2002.04.17 MIK
		delete [] m_pszKinsokuKuto_1;
		m_pszKinsokuKuto_1 = NULL;
	}
	if( NULL != m_pszKinsokuKuto_2 ){	/* 句読点ぶらさげ */	//@@@ 2002.04.17 MIK
		delete [] m_pszKinsokuKuto_2;
		m_pszKinsokuKuto_2 = NULL;
	}

	return;
}


/*
|| レイアウト情報の変更
*/
void CLayoutMgr::SetLayoutInfo(
	int		bDoRayout,
	HWND	hwndProgress,
	Types&	refType			/* タイプ別設定 */
)
{
	MY_RUNNINGTIMER( cRunningTimer, "CLayoutMgr::SetLayoutInfo" );

	m_nMaxLineSize = refType.m_nMaxLineSize;
	m_bWordWrap		= refType.m_bWordWrap;		/* 英文ワードラップをする */
	m_nTabSpace		= refType.m_nTabSpace;
	m_nStringType	= refType.m_nStringType;		/* 文字列区切り記号エスケープ方法 0=[\"][\'] 1=[""][''] */

	m_cLineComment = refType.m_cLineComment;	/* 行コメントデリミタ */	//@@@ 2002.09.22 YAZAKI
	m_cBlockComment = refType.m_cBlockComment;	/* ブロックコメントデリミタ */	//@@@ 2002.09.22 YAZAKI

	//	Oct. 1, 2002 genta タイプによって処理関数を変更する
	//	数が増えてきたらテーブルにすべき
	switch ( refType.m_nIndentLayout ){	/* 折り返しは2行目以降を字下げ表示 */	//@@@ 2002.09.29 YAZAKI
		case 1:
			//	Nov. 16, 2002 メンバー関数ポインタにはクラス名が必要
			getIndentOffset = &CLayoutMgr::getIndentOffset_Tx2x;
			break;
		case 2:
			getIndentOffset = &CLayoutMgr::getIndentOffset_LeftSpace;
			break;
		default:
			getIndentOffset = &CLayoutMgr::getIndentOffset_Normal;
			break;
	}
	
	{	//@@@ 2002.04.08 MIK start
		unsigned char	*p, *q1, *q2, *k1, *k2;
		int	length;

		//句読点のぶらさげ
		m_bKinsokuKuto = refType.m_bKinsokuKuto;	/* 句読点ぶらさげ */	//@@@ 2002.04.17 MIK
		if( NULL != m_pszKinsokuKuto_1 )
		{
			delete [] m_pszKinsokuKuto_1;
			m_pszKinsokuKuto_1 = NULL;
		}
		if( NULL != m_pszKinsokuKuto_2 )
		{
			delete [] m_pszKinsokuKuto_2;
			m_pszKinsokuKuto_2 = NULL;
		}
		//length = strlen( pszKinsokuHead ) + 1;
		//	Kuto_2="。、,.", Kuto_1="??,."
		length = 16;	//これだけあれば十分
		m_pszKinsokuKuto_1 = new char[ length ];
		m_pszKinsokuKuto_2 = new char[ length ];
		k1 = (unsigned char *)m_pszKinsokuKuto_1;
		k2 = (unsigned char *)m_pszKinsokuKuto_2;
		memset( (void *)k1, 0, length );
		memset( (void *)k2, 0, length );
		//データ部は行頭禁則処理で設定する。

		//行頭禁則文字の1,2バイト文字を分けて管理する。
		m_bKinsokuHead = refType.m_bKinsokuHead;
		if( NULL != m_pszKinsokuHead_1 )
		{
			delete [] m_pszKinsokuHead_1;
			m_pszKinsokuHead_1 = NULL;
		}
		if( NULL != m_pszKinsokuHead_2 )
		{
			delete [] m_pszKinsokuHead_2;
			m_pszKinsokuHead_2 = NULL;
		}
		length = strlen( refType.m_szKinsokuHead ) + 1;
		m_pszKinsokuHead_1 = new char[ length ];
		m_pszKinsokuHead_2 = new char[ length ];
		q1 = (unsigned char *)m_pszKinsokuHead_1;
		q2 = (unsigned char *)m_pszKinsokuHead_2;
		memset( (void *)q1, 0, length );
		memset( (void *)q2, 0, length );
		for( p = (unsigned char *)refType.m_szKinsokuHead; *p; p++ )
		{
			if( _IS_SJIS_1( *p ) )
			{
				if( IsKutoTen( *p, *(p+1) ) )	//句読点は別管理
				{
					unsigned char	*r;
					// 2004.11.12 Moca 重複していたら登録しない
					for( r = (unsigned char *)m_pszKinsokuKuto_2; r < k2; r+=2 ){
						if( *r == *p && *(r + 1) == *(p + 1) ){
							break;
						}
					}
					if( r == k2 ){
						*k2 = *p; k2++; p++;
						*k2 = *p; k2++;
						*k2 = 0;
					}
				}
				else
				{
					*q2 = *p; q2++; p++;
					*q2 = *p; q2++;
					*q2 = 0;
				}
			}
			else
			{
				if( IsKutoTen( *p, 0 ) )	//句読点は別管理
				{
					// Dec.23, 2004 genta チェックすべき点が誤っていたので移動
					unsigned char	*r;
					// 2004.11.12 Moca 重複していたら登録しない
					for( r = (unsigned char *)m_pszKinsokuKuto_1; r < k1; r++ ){
						if( *r == *p ){
							break;
						}
					}
					if( r == k1 ){
						*k1 = *p; k1++;
						*k1 = 0;
					}
				}
				else
				{
					*q1 = *p; q1++;
					*q1 = 0;
				}
			}
		}

		//行末禁則文字の1,2バイト文字を分けて管理する。
		m_bKinsokuTail = refType.m_bKinsokuTail;
		if( NULL != m_pszKinsokuTail_1 )
		{
			delete [] m_pszKinsokuTail_1;
			m_pszKinsokuTail_1 = NULL;
		}
		if( NULL != m_pszKinsokuTail_2 )
		{
			delete [] m_pszKinsokuTail_2;
			m_pszKinsokuTail_2 = NULL;
		}
		length = strlen( refType.m_szKinsokuTail ) + 1;
		m_pszKinsokuTail_1 = new char[ length ];
		m_pszKinsokuTail_2 = new char[ length ];
		q1 = (unsigned char *)m_pszKinsokuTail_1;
		q2 = (unsigned char *)m_pszKinsokuTail_2;
		memset( (void *)q1, 0, length );
		memset( (void *)q2, 0, length );
		for( p = (unsigned char *)refType.m_szKinsokuTail; *p; p++ )
		{
			if( _IS_SJIS_1( *p ) )
			{
				*q2 = *p; q2++; p++;
				*q2 = *p; q2++;
				*q2 = 0;
			}
			else
			{
				*q1 = *p; q1++;
				*q1 = 0;
			}
		}

		m_bKinsokuRet = refType.m_bKinsokuRet;	/* 改行文字をぶら下げる */	//@@@ 2002.04.13 MIK

	}	//@@@ 2002.04.08 MIK end

	if( bDoRayout ){
		DoLayout( hwndProgress, refType.m_ColorInfoArr[COLORIDX_SSTRING].m_bDisp, refType.m_ColorInfoArr[COLORIDX_WSTRING].m_bDisp );
	}

	return;
}


/*
||
|| 行データ管理クラスのポインタを初期化します
||
*/
void CLayoutMgr::Create( CEditDoc* pcEditDoc, CDocLineMgr* pcDocLineMgr )
{
	Init();
	//	Jun. 20, 2003 genta EditDocへのポインタ追加
	m_pcEditDoc = pcEditDoc;
	m_pcDocLineMgr = pcDocLineMgr;
	return;
}



void CLayoutMgr::Init()
{
	m_pLayoutTop = NULL;
	m_pLayoutBot = NULL;
	m_nPrevReferLine = 0;
	m_pLayoutPrevRefer = NULL;
//	m_pLayoutCurrent = NULL;
	m_nLines = 0;			/* 全物理行数 */
//	m_pszLineComment = NULL;			/* 行コメントデリミタ */
//	m_pszBlockCommentFrom = NULL;		/* ブロックコメントデリミタ(From) */
//	m_pszBlockCommentTo = NULL;			/* ブロックコメントデリミタ(To) */
	return;
}



void CLayoutMgr::Empty()
{
	CLayout* pLayout;
	CLayout* pLayoutNext;
	pLayout = m_pLayoutTop;
	while( NULL != pLayout ){
		pLayoutNext = pLayout->m_pNext;
		delete pLayout;
		pLayout = pLayoutNext;
	}
	return;
}


/*!
	@brief 指定された物理行のレイアウト情報を取得

	@param nLineNum [in] 物理行番号 (0~)

*/
CLayout* CLayoutMgr::Search( int nLineNum )
{
//#ifdef _DEBUG
//	CRunningTimer cRunningTimer( (const char*)"CLayoutMgr::Search()" );
//#endif
	CLayout*	pLayout;
	int			nCount;
	if( 0 == m_nLines ){
		return NULL;
	}
	//	Mar. 19, 2003 Moca nLineNumが負の場合のチェックを追加
	if( 0 > nLineNum || nLineNum >= m_nLines ){
#ifdef _DEBUG
		if( 0 > nLineNum ){
			MYTRACE( "CLayoutMgr::Search() nLineNum = %d\n", nLineNum );
		}
#endif
		return NULL;
	}
//	/*+++++++ 低速版 +++++++++*/
//	if( nLineNum < (m_nLines / 2) ){
//		nCount = 0;
//		pLayout = m_pLayoutTop;
//		while( NULL != pLayout ){
//			if( nLineNum == nCount ){
//				m_pLayoutPrevRefer = pLayout;
//				m_nPrevReferLine = nLineNum;
//				return pLayout;
//			}
//			pLayout = pLayout->m_pNext;
//			nCount++;
//		}
//	}else{
//		nCount = m_nLines - 1;
//		pLayout = m_pLayoutBot;
//		while( NULL != pLayout ){
//			if( nLineNum == nCount ){
//				m_pLayoutPrevRefer = pLayout;
//				m_nPrevReferLine = nLineNum;
//				return pLayout;
//			}
//			pLayout = pLayout->m_pPrev;
//			nCount--;
//		}
//	}


	/*+++++++わずかに高速版+++++++*/
	// 2004.03.28 Moca m_pLayoutPrevReferより、Top,Botのほうが近い場合は、そちらを利用する
	int nPrevToLineNumDiff = abs( m_nPrevReferLine - nLineNum );
	if( m_pLayoutPrevRefer == NULL
	  || nLineNum < nPrevToLineNumDiff
	  || m_nLines - nLineNum < nPrevToLineNumDiff
	){
		if( nLineNum < (m_nLines / 2) ){
			nCount = 0;
			pLayout = m_pLayoutTop;
			while( NULL != pLayout ){
				if( nLineNum == nCount ){
					m_pLayoutPrevRefer = pLayout;
					m_nPrevReferLine = nLineNum;
					return pLayout;
				}
				pLayout = pLayout->m_pNext;
				nCount++;
			}
		}else{
			nCount = m_nLines - 1;
			pLayout = m_pLayoutBot;
			while( NULL != pLayout ){
				if( nLineNum == nCount ){
					m_pLayoutPrevRefer = pLayout;
					m_nPrevReferLine = nLineNum;
					return pLayout;
				}
				pLayout = pLayout->m_pPrev;
				nCount--;
			}
		}
	}else{
		if( nLineNum == m_nPrevReferLine ){
			return m_pLayoutPrevRefer;
		}else
		if( nLineNum > m_nPrevReferLine ){
			nCount = m_nPrevReferLine + 1;
			pLayout = m_pLayoutPrevRefer->m_pNext;
			while( NULL != pLayout ){
				if( nLineNum == nCount ){
					m_pLayoutPrevRefer = pLayout;
					m_nPrevReferLine = nLineNum;
					return pLayout;
				}
				pLayout = pLayout->m_pNext;
				nCount++;
			}
		}else{
			nCount = m_nPrevReferLine - 1;
			pLayout = m_pLayoutPrevRefer->m_pPrev;
			while( NULL != pLayout ){
				if( nLineNum == nCount ){
					m_pLayoutPrevRefer = pLayout;
					m_nPrevReferLine = nLineNum;
					return pLayout;
				}
				pLayout = pLayout->m_pPrev;
				nCount--;
			}
		}
	}
	return NULL;
}


//@@@ 2002.09.23 YAZAKI CLayout*を作成するところは分離して、InsertLineNext()と共通化
void CLayoutMgr::AddLineBottom( CLayout* pLayout )
{
	if(	0 == m_nLines ){
		m_pLayoutBot = m_pLayoutTop = pLayout;
		m_pLayoutTop->m_pPrev = NULL;
	}else{
		m_pLayoutBot->m_pNext = pLayout;
		pLayout->m_pPrev = m_pLayoutBot;
		m_pLayoutBot = pLayout;
	}
	pLayout->m_pNext = NULL;
	m_nLines++;
	return;
}

//@@@ 2002.09.23 YAZAKI CLayout*を作成するところは分離して、AddLineBottom()と共通化
CLayout* CLayoutMgr::InsertLineNext( CLayout* pLayoutPrev, CLayout* pLayout )
{
	CLayout* pLayoutNext;

	if(	0 == m_nLines ){
		/* 初 */
		m_pLayoutBot = m_pLayoutTop = pLayout;
		m_pLayoutTop->m_pPrev = NULL;
		m_pLayoutTop->m_pNext = NULL;
	}else
	if( NULL == pLayoutPrev ){
		/* 先頭に挿入 */
		m_pLayoutTop->m_pPrev = pLayout;
		pLayout->m_pPrev = NULL;
		pLayout->m_pNext = m_pLayoutTop;
		m_pLayoutTop = pLayout;
	}else
	if( NULL == pLayoutPrev->m_pNext ){
		/* 最後に挿入 */
		m_pLayoutBot->m_pNext = pLayout;
		pLayout->m_pPrev = m_pLayoutBot;
		pLayout->m_pNext = NULL;
		m_pLayoutBot = pLayout;
	}else{
		/* 途中に挿入 */
		pLayoutNext = pLayoutPrev->m_pNext;
		pLayoutPrev->m_pNext = pLayout;
		pLayoutNext->m_pPrev = pLayout;
		pLayout->m_pPrev = pLayoutPrev;
		pLayout->m_pNext = pLayoutNext;
	}
	m_nLines++;
	return pLayout;
}

/* CLayoutを作成する
	@@@ 2002.09.23 YAZAKI
*/
CLayout* CLayoutMgr::CreateLayout( CDocLine* pCDocLine, int nLine, int nOffset, int nLength, int nTypePrev, int nIndent )
{
	CLayout* pLayout = new CLayout;
	pLayout->m_pCDocLine = pCDocLine;

	pLayout->m_nLinePhysical = nLine;
	pLayout->m_nOffset = nOffset;
	pLayout->m_nLength = nLength;
	pLayout->m_nTypePrev = nTypePrev;
	pLayout->m_nIndent = nIndent;

⌨️ 快捷键说明

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