/*!
	ユニコードの使用不使用とか考慮しつつ埋め空白を作る
	@param[in]	dTgtDot	作成するドット数
	@return		LPTSTR	作成したスペースの文字列・開放は呼んだ方で面倒見る
*/
LPTSTR DocPaddingSpaceMake( INT dTgtDot )
{
	LPTSTR	ptReplc = NULL;
	INT		dZenSp, dHanSp, dUniSp;

	//	幅0だと作れない
	if( 0 >= dTgtDot )	return NULL;

	if( gbUniPad )
	{
		ptReplc = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp );
		//	作成不可だったり半角多すぎたら、ユニコード使って作り直し
		if( !(ptReplc) || (dZenSp < dHanSp) )	//	(dZenSp + 1)
		{
			FREE(ptReplc);
			ptReplc = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, &dUniSp );
		}
	}
	else	//	ユニコード空白使わないなら
	{
		ptReplc = DocPaddingSpaceWithGap( dTgtDot, &dZenSp, &dHanSp );
	}

	return ptReplc;
}
/*!
	指定されたドット幅を、ピリオドも使って綺麗に確保する・19幅までなら調整できる・これはこれで必要
	@param[in]	dTgtDot	作成するドット数
	@param[out]	pdZen	使用した全角スペースの個数入れる・NULLでもOK
	@param[out]	pdHan	使用した半角スペースの個数入れる・NULLでもOK
	@param[out]	pdPrd	使用したピリオドの個数入れる・NULLでもOK
	@param[in]	bFull	固定テーブルつかって強引にあわせる?
	@return		LPTSTR	作成したスペースの文字列・開放は呼んだ方で面倒見る・作成不可ならNULL
*/
LPTSTR DocPaddingSpaceWithPeriod( INT dTgtDot, PINT pdZen, PINT pdHan, PINT pdPrd, BOOLEAN bFull )
{
	INT	dZenSp, dHanSp, dPrdSp, m, dPre;
	LPTSTR	ptSpace = NULL, ptPlus = NULL;
	UINT	cchSize, cchPlus;


	dPre = dTgtDot;
	dPrdSp = 0;

	do{
		dZenSp =  0;	dHanSp =  0;
		ptSpace = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp );

		//	作成不可だった場合	半角多すぎても不可
		if( !(ptSpace) || (dZenSp < dHanSp) )	//	(dZenSp + 1)
		{
			FREE(ptSpace);
			if( gbUniPad )	//	上手くいかないようなら、ユニコード使ってやり直す
			{
				ptSpace = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, NULL );
				break;
			}
			else
			{
				dPrdSp++;	dTgtDot -= 3;	//	ピリオドは3ドット
			}
		}
		else	//	問題無い文字列ならおk
		{
			break;
		}

	}while( dTgtDot >= 19 );	//	これ以上は不可?

	if( !(ptSpace) && bFull )	//	まだ制作できてなく、固定テーブル使うなら
	{
		dPrdSp = 0;
		dTgtDot = dPre;

		StringCchLength( gaatPaddingSpDot[dTgtDot], STRSAFE_MAX_CCH, &cchSize );

		cchSize += 1;
		ptSpace = (LPTSTR)malloc( cchSize * sizeof(TCHAR) );
		ZeroMemory( ptSpace, cchSize * sizeof(TCHAR) );

		StringCchCopy( ptSpace, cchSize, gaatPaddingSpDot[dTgtDot] );
	}

	if( ptSpace )
	{
		StringCchLength( ptSpace, STRSAFE_MAX_CCH, &cchSize );
		
		//	ピリオド入れてサイズ調整
		cchPlus = cchSize + dPrdSp + 1;
		ptPlus = (LPTSTR)malloc( cchPlus * sizeof(TCHAR) );
		ZeroMemory( ptPlus, cchPlus * sizeof(TCHAR) );

		StringCchCopy( ptPlus, cchPlus, ptSpace );
		FREE(ptSpace);	//	スペースおしまい

		//	複数ピリオドあったら前後につけるようにしたい
		for( m = 0; dPrdSp > m; m++ ){	StringCchCat( ptPlus , cchPlus, TEXT(".") );	}
	}


	if( pdZen  )	*pdZen = dZenSp;
	if( pdHan  )	*pdHan = dHanSp;
	if( pdPrd  )	*pdPrd = dPrdSp;

	return ptPlus;
}
/*!
	現在のドット位置を含んでいる空白エリアを1ドットずつずらす
	@param[in]	vk		方向・右か左か
	@param[in]	pXdot	今のドット位置を受けて戻す
	@param[in]	dLine	今の行数
	@param[in]	dFirst	アンドゥグループ・非0なら最初の一発 0続き
	@return	UINT	非0ズレ値 0失敗
*/
UINT DocSpaceDifference( UINT vk, PINT pXdot, INT dLine, UINT dFirst )
{
	INT			dTgtDot, dNowDot;
	INT			dBgnDot, dEndDot;
	INT			dBgnCnt, dRngCnt;
	UINT_PTR	cchSize;
	BOOLEAN		bIsSpace;
	LPTSTR		ptSpace;//, ptOldSp;
	INT			dZenSp, dHanSp, dUniSp;
	INT			iDots, iBytes;

	wstring		wsBuffer;
	LETR_ITR	vcLtrBgn, vcLtrEnd, vcItr;

	LINE_ITR	itLine;

	itLine = (*gitFileIt).vcCont.at( gixFocusPage ).ltPage.begin();
	std::advance( itLine, dLine );

	dNowDot = *pXdot;

	if( 0 == dNowDot )	//	0の場合は強引に移動
	{
		dNowDot = itLine->vcLine.at( 0 ).rdWidth;
	}

	dTgtDot = DocLineStateCheckWithDot( dNowDot, dLine, &dBgnDot, &dEndDot, &dBgnCnt, &dRngCnt, &bIsSpace );
	if( !(bIsSpace) )	return 0;	//	非スペースエリアは意味が無い

	if( VK_RIGHT == vk )		dTgtDot++;	//	右なら増やすってこと
	else if( VK_LEFT == vk )	dTgtDot--;
	else	return 0;	//	関係ないのはアウツ

	//	当てはめるアレを計算する
	ptSpace = DocPaddingSpace( dTgtDot, &dZenSp, &dHanSp );
	if( gbUniPad )
	{
		//	作成不可だったり半角多すぎたら、ユニコード使って作り直し
		if( !(ptSpace) || (dZenSp < dHanSp) )	//	(dZenSp + 1)
		{
			FREE(ptSpace);
			ptSpace = DocPaddingSpaceUni( dTgtDot, &dZenSp, &dHanSp, &dUniSp );
		}
	}

	if( !(ptSpace) )	return 0;	//	作成不可だった場合


	StringCchLength( ptSpace, STRSAFE_MAX_CCH, &cchSize );

	vcLtrBgn  = itLine->vcLine.begin( );
	vcLtrBgn += dBgnCnt;	//	該当位置まで移動して
	vcLtrEnd  = vcLtrBgn;
	vcLtrEnd += dRngCnt;	//	そのエリアの終端も確認

	iDots = 0;	iBytes = 0;
	wsBuffer.clear();
	for( vcItr = vcLtrBgn; vcLtrEnd != vcItr; vcItr++ )
	{
		wsBuffer += vcItr->cchMozi;
		iDots    += vcItr->rdWidth;
		iBytes   += vcItr->mzByte;
	}

	//	該当部分を一旦削除・アンドゥリドゥするなら内容を記録する必要がある
	itLine->vcLine.erase( vcLtrBgn, vcLtrEnd );
	itLine->iByteSz -= iBytes;	if( 0 > itLine->iByteSz ){	itLine->iByteSz = 0;	}
	itLine->iDotCnt -= iDots;	if( 0 > itLine->iDotCnt ){	itLine->iDotCnt = 0;	}

//	DocLineParamGet( yLine, NULL, NULL );	//	行内容の再計算
//あとの函数内で呼ばれまくってる

	//	Space文字列を追加
	dNowDot = dBgnDot;
	DocStringAdd( &dNowDot, &dLine, ptSpace, cchSize );

	*pXdot = dNowDot;

//	cchSize = wsBuffer.size( ) + 1;
//	ptOldSp = (LPTSTR)malloc( cchSize * sizeof(TCHAR) );
//	StringCchCopy( ptOldSp, cchSize, wsBuffer.c_str( ) );

	SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_DELETE, wsBuffer.c_str( ), dBgnDot, dLine, dFirst );
	SqnAppendString( &((*gitFileIt).vcCont.at( gixFocusPage ).stUndoLog), DO_INSERT, ptSpace, dBgnDot, dLine, FALSE );	//	弐回目なので確定でよろし

//	FREE( ptOldSp );

	FREE( ptSpace );

	return dTgtDot;
}
示例#4
0
/*!
	編集の選択範囲からいただく
	@param[in]	hWnd	ウインドウハンドル
	@param[in]	bSqSel	矩形であるかどうか
*/
UINT DraughtItemAddFromSelect( HWND hWnd, UINT bSqSel )
{
	LPTSTR	ptString = NULL;
	UINT	cchSize, cbSize;
	LPPOINT	pstPos = NULL;

	UINT_PTR	i, j, iTexts;
	LONG	dMin = 0;
	INT		insDot, yLine, iLines = 0, dOffset;
	LPTSTR	ptSpace = NULL;

	LPSTR	pcArts;
	wstring	wsString;


	//	内部処理なのでUnicode固定
	cbSize = DocSelectTextGetAlloc( D_UNI | bSqSel, (LPVOID *)(&ptString), (bSqSel & D_SQUARE) ? &pstPos : NULL );

	StringCchLength( ptString, STRSAFE_MAX_CCH, &cchSize );

	if( 0 >= cchSize )	return 0;	//	文字列ないならなにもしない

	//	オフセット設定が有る場合、その分を埋める空白が必要
	if( pstPos )	//	最小オフセット値を探して、そこを左端にする
	{
		dMin = pstPos[0].x;

		yLine = 0;
		for( i = 0; cchSize > i; i++ )
		{
			if( CC_CR == ptString[i] && CC_LF == ptString[i+1] )	//	改行であったら
			{
				//	オフセット最小をさがす
				if( dMin > pstPos[yLine].x ){	dMin =  pstPos[yLine].x;	}

				i++;		//	0x0D,0x0Aだから、壱文字飛ばすのがポイント
				yLine++;	//	改行したからFocusは次の行へ
			}
		}
		//	この時点で、yLineは行数になってる
		iLines = yLine;

		//	壱行目の空白を作って閃光入力しておく
		insDot = 0;
		dOffset = pstPos[0].x - dMin;
		ptSpace = DocPaddingSpaceUni( dOffset, NULL, NULL, NULL );
		//	前方空白は無視されるのでユニコード使って問題無い
		StringCchLength( ptSpace, STRSAFE_MAX_CCH, &iTexts );
		for( j = 0; iTexts > j; j++ ){	wsString +=  ptSpace[j];	}
		FREE(ptSpace);
	}

	yLine = 0;	insDot = 0;
	for( i = 0; cchSize > i; i++ )
	{
		if( CC_CR == ptString[i] && CC_LF == ptString[i+1] )	//	改行であったら
		{
			wsString +=  wstring( TEXT("\r\n") );

			i++;		//	0x0D,0x0Aだから、壱文字飛ばすのがポイント
			yLine++;	//	改行したからFocusは次の行へ

			//	オフセット分の空白を作る
			if( pstPos && (iLines > yLine) )
			{
				dOffset = pstPos[yLine].x - dMin;
				ptSpace = DocPaddingSpaceUni( dOffset, NULL, NULL, NULL );
				//	前方空白は無視されるのでユニコード使って問題無い
				StringCchLength( ptSpace, STRSAFE_MAX_CCH, &iTexts );
				for( j = 0; iTexts > j; j++ ){	wsString +=  ptSpace[j];	}
				FREE(ptSpace);
			}
		}
		else if( CC_TAB ==  ptString[i] ){	/*	タブは挿入しない	*/	}
		else{	wsString += ptString[i];	}
	}

	FREE(ptString);
	FREE(pstPos);

	pcArts =  SjisEncodeAlloc( wsString.c_str() );

	DraughtItemAdding( hWnd, pcArts );

	FREE(pcArts);

	return yLine;
}