📄 clayoutmgr.cpp
字号:
// $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 + -