File Annotation

Not logged in
dcdd144598 2011-02-23        kinaba: #include "stdafx.h"
dcdd144598 2011-02-23        kinaba: #include "ip_view.h"
dcdd144598 2011-02-23        kinaba: using namespace editwing;
dcdd144598 2011-02-23        kinaba: using namespace editwing::view;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: //---- ip_draw.cpp   描画・他
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //		折り返しとか色とかを考慮しつつ、実際に描画処理を
dcdd144598 2011-02-23        kinaba: //		行うのがここ。あとメッセージディスパッチャなども
dcdd144598 2011-02-23        kinaba: //		ついでにこのファイルに。^^;
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //---- ip_text.cpp   文字列操作・他
dcdd144598 2011-02-23        kinaba: //---- ip_parse.cpp  キーワード解析
dcdd144598 2011-02-23        kinaba: //---- ip_wrap.cpp   折り返し
dcdd144598 2011-02-23        kinaba: //---- ip_scroll.cpp スクロール
dcdd144598 2011-02-23        kinaba: //---- ip_cursor.cpp カーソルコントロール
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // Viewの初期化・解放
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: View::ClsName
dcdd144598 2011-02-23        kinaba: 	View::className_ = TEXT("EditWing View");
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: View::View( doc::Document& d, HWND wnd )
dcdd144598 2011-02-23        kinaba: 	: WndImpl( className_, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL )
dcdd144598 2011-02-23        kinaba: 	, doc_   ( d.impl() )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	static bool ClassRegistered = false;
dcdd144598 2011-02-23        kinaba: 	if( !ClassRegistered )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// 初回構築時のみ、クラス登録を行う
dcdd144598 2011-02-23        kinaba: 		ClassRegistered = true;
dcdd144598 2011-02-23        kinaba: 		WNDCLASSEX wc    = {0};
dcdd144598 2011-02-23        kinaba: 		wc.lpszClassName = className_;
dcdd144598 2011-02-23        kinaba: 		wc.style         = CS_DBLCLKS | CS_OWNDC;
dcdd144598 2011-02-23        kinaba: 		wc.hCursor       = app().LoadOemCursor( IDC_IBEAM );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// GlobalIMEを有効にする
dcdd144598 2011-02-23        kinaba: 		ATOM a = WndImpl::Register( &wc );
dcdd144598 2011-02-23        kinaba: 		ime().FilterWindows( &a, 1 );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 窓作成
dcdd144598 2011-02-23        kinaba: 	Create( NULL, wnd );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: View::~View()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 窓破棄
dcdd144598 2011-02-23        kinaba: 	Destroy();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::on_create( CREATESTRUCT* cs )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	impl_ = new ViewImpl( *this, doc_ );
dcdd144598 2011-02-23        kinaba: 	doc_.AddHandler( this );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::on_destroy()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	doc_.DelHandler( this );
dcdd144598 2011-02-23        kinaba: 	impl_ = NULL;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // サブオブジェクトにそのまま回す
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::SetWrapType( int wt )
dcdd144598 2011-02-23        kinaba: 	{ impl_->SetWrapType( wt ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::ShowLineNo( bool show )
dcdd144598 2011-02-23        kinaba: 	{ impl_->ShowLineNo( show ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::SetFont( const VConfig& vc )
dcdd144598 2011-02-23        kinaba: 	{ impl_->SetFont( vc ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::on_keyword_change()
dcdd144598 2011-02-23        kinaba: 	{ ::InvalidateRect( hwnd(), NULL, FALSE ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void View::on_text_update
dcdd144598 2011-02-23        kinaba:   ( const DPos& s, const DPos& e, const DPos& e2, bool bAft, bool mCur )
dcdd144598 2011-02-23        kinaba: 	{ impl_->on_text_update( s, e, e2, bAft, mCur ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: Cursor& View::cur()
dcdd144598 2011-02-23        kinaba: 	{ return impl_->cur(); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: LRESULT View::on_message( UINT msg, WPARAM wp, LPARAM lp )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	switch( msg )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case WM_PAINT:{
dcdd144598 2011-02-23        kinaba: 		PAINTSTRUCT ps;
dcdd144598 2011-02-23        kinaba: 		::BeginPaint( hwnd(), &ps );
dcdd144598 2011-02-23        kinaba: 		impl_->on_paint( ps );
dcdd144598 2011-02-23        kinaba: 		::EndPaint( hwnd(), &ps );
dcdd144598 2011-02-23        kinaba: 		}break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_SIZE:
dcdd144598 2011-02-23        kinaba: 		impl_->on_view_resize( LOWORD(lp), HIWORD(lp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_HSCROLL:
dcdd144598 2011-02-23        kinaba: 		impl_->on_hscroll( LOWORD(wp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_VSCROLL:
dcdd144598 2011-02-23        kinaba: 		impl_->on_vscroll( LOWORD(wp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_MOUSEWHEEL:
dcdd144598 2011-02-23        kinaba: 		impl_->on_wheel( HIWORD(wp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_SETFOCUS:
dcdd144598 2011-02-23        kinaba: 		cur().on_setfocus();
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_KILLFOCUS:
dcdd144598 2011-02-23        kinaba: 		cur().on_killfocus();
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_TIMER:
dcdd144598 2011-02-23        kinaba: 		cur().on_timer();
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_KEYDOWN:
dcdd144598 2011-02-23        kinaba: 		cur().on_keydown( (int)wp, lp );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_CHAR:
dcdd144598 2011-02-23        kinaba: 		cur().on_char( (TCHAR)wp );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_LBUTTONDOWN:
dcdd144598 2011-02-23        kinaba: 		cur().on_lbutton_down( LOWORD(lp), HIWORD(lp), (wp&MK_SHIFT)!=0 );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_LBUTTONUP:
dcdd144598 2011-02-23        kinaba: 		cur().on_lbutton_up( LOWORD(lp), HIWORD(lp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_LBUTTONDBLCLK:
dcdd144598 2011-02-23        kinaba: 		cur().on_lbutton_dbl( LOWORD(lp), HIWORD(lp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_MOUSEMOVE:
dcdd144598 2011-02-23        kinaba: 		cur().on_mouse_move( LOWORD(lp), HIWORD(lp) );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_CONTEXTMENU:
dcdd144598 2011-02-23        kinaba: 		if( !cur().on_contextmenu( LOWORD(lp), HIWORD(lp) ) )
dcdd144598 2011-02-23        kinaba: 			return WndImpl::on_message( msg, wp, lp );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_IME_REQUEST:
dcdd144598 2011-02-23        kinaba: 		switch( wp )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 		case IMR_RECONVERTSTRING:
dcdd144598 2011-02-23        kinaba: 			return cur().on_ime_reconvertstring(
dcdd144598 2011-02-23        kinaba: 				reinterpret_cast<RECONVERTSTRING*>(lp) );
dcdd144598 2011-02-23        kinaba: 		case IMR_CONFIRMRECONVERTSTRING:
dcdd144598 2011-02-23        kinaba: 			return cur().on_ime_confirmreconvertstring(
dcdd144598 2011-02-23        kinaba: 				reinterpret_cast<RECONVERTSTRING*>(lp) );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_IME_STARTCOMPOSITION:
dcdd144598 2011-02-23        kinaba: 		cur().on_ime_composition( 0 );
dcdd144598 2011-02-23        kinaba: 		return WndImpl::on_message( msg, wp, lp );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case WM_IME_COMPOSITION:
dcdd144598 2011-02-23        kinaba: 		cur().on_ime_composition( lp );
dcdd144598 2011-02-23        kinaba: 		if( lp&GCS_RESULTSTR )
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		// fall through...
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	default:
dcdd144598 2011-02-23        kinaba: 		return WndImpl::on_message( msg, wp, lp );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	return 0;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // 線を引くとか四角く塗るとか、そーいう基本的な処理
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: Painter::Painter( HDC hdc, const VConfig& vc )
dcdd144598 2011-02-23        kinaba: 	: dc_        ( hdc )
dcdd144598 2011-02-23        kinaba: 	, font_      ( ::CreateFontIndirect( &vc.font ) )
dcdd144598 2011-02-23        kinaba: 	, pen_       ( ::CreatePen( PS_SOLID, 0, vc.color[CTL] ) )
dcdd144598 2011-02-23        kinaba: 	, brush_     ( ::CreateSolidBrush( vc.color[BG] ) )
dcdd144598 2011-02-23        kinaba: 	, widthTable_( new int[65536] )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 制御文字を描画するか否か?のフラグを記憶
dcdd144598 2011-02-23        kinaba: 	for( int i=0; i<countof(scDraw_); ++i )
dcdd144598 2011-02-23        kinaba: 		scDraw_[i] = vc.sc[i];
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 文字色を記憶
dcdd144598 2011-02-23        kinaba: 	for( int i=0; i<countof(colorTable_); ++i )
dcdd144598 2011-02-23        kinaba: 		colorTable_[i] = vc.color[i];
dcdd144598 2011-02-23        kinaba: 		colorTable_[3] = vc.color[CMT];
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// DCにセット
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, font_  );
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, pen_   );
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, brush_ );
dcdd144598 2011-02-23        kinaba: 	::SetBkMode(    dc_, TRANSPARENT );
dcdd144598 2011-02-23        kinaba: 	::SetMapMode(   dc_, MM_TEXT );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 文字幅テーブル初期化(ASCII範囲の文字以外は遅延処理)
dcdd144598 2011-02-23        kinaba: 	memFF( widthTable_, 65536*sizeof(int) );
dcdd144598 2011-02-23        kinaba: 	::GetCharWidthW( dc_, L' ', L'~', widthTable_+L' ' );
dcdd144598 2011-02-23        kinaba: 	widthTable_[L'\t'] = W() * Max(1,vc.tabstep);
dcdd144598 2011-02-23        kinaba: 	// 下位サロゲートは文字幅ゼロ
dcdd144598 2011-02-23        kinaba: 	mem00( widthTable_+0xDC00, (0xE000 - 0xDC00)*sizeof(int) );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 数字の最大幅を計算
dcdd144598 2011-02-23        kinaba: 	figWidth_ = 0;
dcdd144598 2011-02-23        kinaba: 	for( unicode ch=L'0'; ch<=L'9'; ++ch )
dcdd144598 2011-02-23        kinaba: 		if( figWidth_ < widthTable_[ch] )
dcdd144598 2011-02-23        kinaba: 			figWidth_ = widthTable_[ch];
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 高さの情報
dcdd144598 2011-02-23        kinaba: 	TEXTMETRIC met;
dcdd144598 2011-02-23        kinaba: 	::GetTextMetrics( dc_, &met );
dcdd144598 2011-02-23        kinaba: 	height_ = met.tmHeight;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// LOGFONT
dcdd144598 2011-02-23        kinaba: 	::GetObject( font_, sizeof(LOGFONT), &logfont_ );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: Painter::~Painter()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 適当な別オブジェクトをくっつけて自分を解放する
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, ::GetStockObject( OEM_FIXED_FONT ) );
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, ::GetStockObject( BLACK_PEN ) );
dcdd144598 2011-02-23        kinaba: 	::SelectObject( dc_, ::GetStockObject( WHITE_BRUSH ) );
dcdd144598 2011-02-23        kinaba: 	::DeleteObject( font_ );
dcdd144598 2011-02-23        kinaba: 	::DeleteObject( pen_ );
dcdd144598 2011-02-23        kinaba: 	::DeleteObject( brush_ );
dcdd144598 2011-02-23        kinaba: 	delete [] widthTable_;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::CharOut( unicode ch, int x, int y )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::TextOutW( dc_, x, y, &ch, 1 );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::StringOut
dcdd144598 2011-02-23        kinaba: 	( const unicode* str, int len, int x, int y )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::TextOutW( dc_, x, y, str, len );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::SetColor( int i )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::SetTextColor( dc_, colorTable_[i] );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::Fill( const RECT& rc )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::FillRect( dc_, &rc, brush_ );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::Invert( const RECT& rc )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::InvertRect( dc_, &rc );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::DrawLine( int x1, int y1, int x2, int y2 )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::MoveToEx( dc_, x1, y1, NULL );
dcdd144598 2011-02-23        kinaba: 	::LineTo( dc_, x2, y2 );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::SetClip( const RECT& rc )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::IntersectClipRect( dc_, rc.left, rc.top, rc.right, rc.bottom );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void Painter::ClearClip()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	::SelectClipRgn( dc_, NULL );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void Painter::DrawHSP( int x, int y, int times )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 半角スペース記号(ホチキスの芯型)を描く
dcdd144598 2011-02-23        kinaba: 	const int w=Wc(L' '), h=H();
dcdd144598 2011-02-23        kinaba: 	POINT pt[4] = {
dcdd144598 2011-02-23        kinaba: 		{ x    , y+h-4 },
dcdd144598 2011-02-23        kinaba: 		{ x    , y+h-2 },
dcdd144598 2011-02-23        kinaba: 		{ x+w-3, y+h-2 },
dcdd144598 2011-02-23        kinaba: 		{ x+w-3, y+h-5 }
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 	while( times-- )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( 0 <= pt[3].x )
dcdd144598 2011-02-23        kinaba: 			::Polyline( dc_, pt, countof(pt) );
dcdd144598 2011-02-23        kinaba: 		pt[0].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[1].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[2].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[3].x += w;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void Painter::DrawZSP( int x, int y, int times )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 全角スペース記号(平たい四角)を描く
dcdd144598 2011-02-23        kinaba: 	const int w=Wc(0x3000/*L' '*/), h=H();
dcdd144598 2011-02-23        kinaba: 	POINT pt[4] = {
dcdd144598 2011-02-23        kinaba: 		{ x    , y+h-4 },
dcdd144598 2011-02-23        kinaba: 		{ x    , y+h-2 },
dcdd144598 2011-02-23        kinaba: 		{ x+w-3, y+h-2 },
dcdd144598 2011-02-23        kinaba: 		{ x+w-3, y+h-4 }
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 	while( times-- )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( 0 <= pt[3].x )
dcdd144598 2011-02-23        kinaba: 			::Polygon( dc_, pt, countof(pt) );
dcdd144598 2011-02-23        kinaba: 		pt[0].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[1].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[2].x += w;
dcdd144598 2011-02-23        kinaba: 		pt[3].x += w;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // 再描画したい範囲を Invalidate する。
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void ViewImpl::ReDraw( ReDrawType r, const DPos* s )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// まずスクロールバーを更新
dcdd144598 2011-02-23        kinaba: 	UpdateScrollBar();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	switch( r )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case ALL: // 全画面
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		::InvalidateRect( hwnd_, NULL, FALSE );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case LNAREA: // 行番号表示域のみ
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		if( lna() > 0 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			RECT rc = { 0, 0, lna(), bottom() };
dcdd144598 2011-02-23        kinaba: 			::InvalidateRect( hwnd_, &rc, FALSE );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	case LINE: // 指定した行の後半
dcdd144598 2011-02-23        kinaba: 	case AFTER: // 指定した行以下全部
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			DPos st = ( s->ad==0 ? *s : doc_.leftOf(*s,true) );
dcdd144598 2011-02-23        kinaba: 			InvalidateView( st, r==AFTER );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // WM_PAINTハンドラ
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void ViewImpl::on_paint( const PAINTSTRUCT& ps )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 描画範囲の情報を詳しく取得
dcdd144598 2011-02-23        kinaba: 	Painter& p = cvs_.getPainter();
dcdd144598 2011-02-23        kinaba: 	VDrawInfo v( ps.rcPaint );
dcdd144598 2011-02-23        kinaba: 	GetDrawPosInfo( v );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( ps.rcPaint.right <= lna()  )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// case A: 行番号表示域のみ更新
dcdd144598 2011-02-23        kinaba: 		DrawLNA( v, p );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	else if( lna() <= ps.rcPaint.left )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// case B: テキスト表示域のみ更新
dcdd144598 2011-02-23        kinaba: 		DrawTXT( v, p );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	else
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// case C: 両方更新
dcdd144598 2011-02-23        kinaba: 		DrawLNA( v, p );
dcdd144598 2011-02-23        kinaba: 		p.SetClip( cvs_.zone() );
dcdd144598 2011-02-23        kinaba: 		DrawTXT( v, p );
dcdd144598 2011-02-23        kinaba: 		p.ClearClip();
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // 行番号ゾーン描画
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void ViewImpl::DrawLNA( const VDrawInfo& v, Painter& p )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	//
dcdd144598 2011-02-23        kinaba: 	// 文字列のまま足し算を行うルーチン
dcdd144598 2011-02-23        kinaba: 	//
dcdd144598 2011-02-23        kinaba: 	struct strint {
dcdd144598 2011-02-23        kinaba: 		strint( ulong num ) {
dcdd144598 2011-02-23        kinaba: 			int i=11;
dcdd144598 2011-02-23        kinaba: 			while( num ) digit[--i] = (unicode)(L'0'+(num%10)), num/=10;
dcdd144598 2011-02-23        kinaba: 			while(  i  ) digit[--i] = L' ';
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		void operator++() {
dcdd144598 2011-02-23        kinaba: 			int i=10;
dcdd144598 2011-02-23        kinaba: 			do
dcdd144598 2011-02-23        kinaba: 				if( digit[i] == L'9' )
dcdd144598 2011-02-23        kinaba: 					digit[i] = L'0';
dcdd144598 2011-02-23        kinaba: 				else
dcdd144598 2011-02-23        kinaba: 					{ ++digit[i]; return; }
dcdd144598 2011-02-23        kinaba: 			while( digit[--i] != L' ' );
dcdd144598 2011-02-23        kinaba: 			digit[i] = L'1';
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		void Output( Painter& f, int x, int y ) {
dcdd144598 2011-02-23        kinaba: 			for( unicode* p=digit+10; *p!=L' '; --p,x-=f.F() )
dcdd144598 2011-02-23        kinaba: 				f.CharOut( *p, x, y );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		unicode digit[11];
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 背面消去
dcdd144598 2011-02-23        kinaba: 	RECT rc = { v.rc.left, v.rc.top, lna(), v.rc.bottom };
dcdd144598 2011-02-23        kinaba: 	p.Fill( rc );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( v.rc.top < v.YMAX )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// 境界線表示
dcdd144598 2011-02-23        kinaba: 		int line = lna() - p.F()/2;
dcdd144598 2011-02-23        kinaba: 		p.DrawLine( line, v.rc.top, line, v.YMAX );
dcdd144598 2011-02-23        kinaba: 		p.SetColor( LN );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 行番号表示
dcdd144598 2011-02-23        kinaba: 		strint n = v.TLMIN+1;
dcdd144598 2011-02-23        kinaba: 		int    y = v.YMIN;
dcdd144598 2011-02-23        kinaba: 		int edge = lna() - p.F()*2;
dcdd144598 2011-02-23        kinaba: 		for( ulong i=v.TLMIN; y<v.YMAX; ++i,++n )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			n.Output( p, edge, y );
dcdd144598 2011-02-23        kinaba: 			y += p.H() * rln(i);
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // テキスト描画
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: inline void ViewImpl::Inv( int y, int xb, int xe, Painter& p )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	RECT rc = {
dcdd144598 2011-02-23        kinaba: 		Max( left(),  xb ), y,
dcdd144598 2011-02-23        kinaba: 		Min( right(), xe ), y+p.H()-1
dcdd144598 2011-02-23        kinaba: 	};
dcdd144598 2011-02-23        kinaba: 	p.Invert( rc );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void ViewImpl::DrawTXT( const VDrawInfo v, Painter& p )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// 定数1
dcdd144598 2011-02-23        kinaba: //	const int   TAB = p.T();
dcdd144598 2011-02-23        kinaba: 	const int     H = p.H();
dcdd144598 2011-02-23        kinaba: 	const ulong TLM = doc_.tln()-1;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 作業用変数1
dcdd144598 2011-02-23        kinaba: 	RECT  a = { 0, v.YMIN, 0, v.YMIN+p.H() };
dcdd144598 2011-02-23        kinaba: 	int clr = -1;
dcdd144598 2011-02-23        kinaba: 	register int   x, x2;
dcdd144598 2011-02-23        kinaba: 	register ulong i, i2;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 論理行単位のLoop
dcdd144598 2011-02-23        kinaba: 	for( ulong tl=v.TLMIN; a.top<v.YMAX; ++tl )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// 定数2
dcdd144598 2011-02-23        kinaba: 		const unicode* str = doc_.tl(tl);
dcdd144598 2011-02-23        kinaba: 		const uchar*   flg = doc_.pl(tl);
dcdd144598 2011-02-23        kinaba: 		const int rYMAX = Min<int>( v.YMAX, a.top+rln(tl)*H );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 作業用変数2
dcdd144598 2011-02-23        kinaba: 		ulong stt=0, end, t, n;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 表示行単位のLoop
dcdd144598 2011-02-23        kinaba: 		for( ulong rl=0; a.top<rYMAX; ++rl,a.top+=H,a.bottom+=H,stt=end )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			// 作業用変数3
dcdd144598 2011-02-23        kinaba: 			end = rlend(tl,rl);
dcdd144598 2011-02-23        kinaba: 			if( a.bottom<=v.YMIN )
dcdd144598 2011-02-23        kinaba: 				continue;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// テキストデータ描画
dcdd144598 2011-02-23        kinaba: 			for( x2=x=0,i2=i=stt; x<=v.XMAX && i<end; x=x2,i=i2 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// n := 次のTokenの頭
dcdd144598 2011-02-23        kinaba: 				t = (flg[i]>>5);
dcdd144598 2011-02-23        kinaba: 				n = i + t;
dcdd144598 2011-02-23        kinaba: 				if( n >= end )
dcdd144598 2011-02-23        kinaba: 					n = end;
dcdd144598 2011-02-23        kinaba: 				else if( t==7 || t==0 )
dcdd144598 2011-02-23        kinaba: 					while( n<end && (flg[n]>>5)==0 )
dcdd144598 2011-02-23        kinaba: 						++n;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// x2, i2 := このTokenの右端
dcdd144598 2011-02-23        kinaba: 				i2 ++;
dcdd144598 2011-02-23        kinaba: 				x2 = (str[i]==L'\t' ? p.nextTab(x2) : x2+p.W(&str[i]));
dcdd144598 2011-02-23        kinaba: 			//	if( x2 <= v.XMIN )
dcdd144598 2011-02-23        kinaba: 			//		x=x2, i=i2;
dcdd144598 2011-02-23        kinaba: 				while( i2<n && x2<=v.XMAX )
dcdd144598 2011-02-23        kinaba: 					x2 += p.W( &str[i2++] );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// 再描画すべき範囲と重なっていない
dcdd144598 2011-02-23        kinaba: 				if( x2<=v.XMIN )
dcdd144598 2011-02-23        kinaba: 					continue;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// x, i := このトークンの左端
dcdd144598 2011-02-23        kinaba: 				if( x<v.XMIN )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// tabの分が戻りすぎ?
dcdd144598 2011-02-23        kinaba: 					x = x2, i = i2;
dcdd144598 2011-02-23        kinaba: 					while( v.XMIN<x )
dcdd144598 2011-02-23        kinaba: 						x -= p.W( &str[--i] );
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// 背景塗りつぶし
dcdd144598 2011-02-23        kinaba: 				a.left  = x + v.XBASE;
dcdd144598 2011-02-23        kinaba: 				a.right = x2 + v.XBASE;
dcdd144598 2011-02-23        kinaba: 				p.Fill( a );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// 描画
dcdd144598 2011-02-23        kinaba: 				switch( str[i] )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 				case L'\t':
dcdd144598 2011-02-23        kinaba: 					if( p.sc(scTAB) )
dcdd144598 2011-02-23        kinaba: 					{
dcdd144598 2011-02-23        kinaba: 						p.SetColor( clr=CTL );
dcdd144598 2011-02-23        kinaba: 						for( ; i<i2; ++i, x=p.nextTab(x) )
dcdd144598 2011-02-23        kinaba: 							p.CharOut( L'>', x+v.XBASE, a.top );
dcdd144598 2011-02-23        kinaba: 					}
dcdd144598 2011-02-23        kinaba: 					break;
dcdd144598 2011-02-23        kinaba: 				case L' ':
dcdd144598 2011-02-23        kinaba: 					if( p.sc(scHSP) )
dcdd144598 2011-02-23        kinaba: 						p.DrawHSP( x+v.XBASE, a.top, i2-i );
dcdd144598 2011-02-23        kinaba: 					break;
dcdd144598 2011-02-23        kinaba: 				case 0x3000://L' ':
dcdd144598 2011-02-23        kinaba: 					if( p.sc(scZSP) )
dcdd144598 2011-02-23        kinaba: 						p.DrawZSP( x+v.XBASE, a.top, i2-i );
dcdd144598 2011-02-23        kinaba: 					break;
dcdd144598 2011-02-23        kinaba: 				default:
dcdd144598 2011-02-23        kinaba: 					if( clr != (flg[i]&3) )
dcdd144598 2011-02-23        kinaba: 						p.SetColor( clr=(flg[i]&3) );
dcdd144598 2011-02-23        kinaba: 					p.StringOut( str+i, i2-i, x+v.XBASE, a.top );
dcdd144598 2011-02-23        kinaba: 					//p.StringOut( str+i, i2-i, x+v.XBASE, a.top );
dcdd144598 2011-02-23        kinaba: 					// 何故だか2度描きしないとうまくいかん…
dcdd144598 2011-02-23        kinaba: 					break;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 選択範囲だったら反転
dcdd144598 2011-02-23        kinaba: 			if( v.SYB<=a.top && a.top<=v.SYE )
dcdd144598 2011-02-23        kinaba: 				Inv( a.top, a.top==v.SYB?v.SXB:(v.XBASE),
dcdd144598 2011-02-23        kinaba: 				            a.top==v.SYE?v.SXE:(v.XBASE+x), p );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			// 行末より後ろの余白を背景色塗
dcdd144598 2011-02-23        kinaba: 			if( x<v.XMAX )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				a.left = v.XBASE + Max( v.XMIN, x );
dcdd144598 2011-02-23        kinaba: 				a.right= v.XBASE + v.XMAX;
dcdd144598 2011-02-23        kinaba: 				p.Fill( a );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 行末記号描画反転
dcdd144598 2011-02-23        kinaba: 		SpecialChars sc = (tl==TLM ? scEOF : scEOL);
dcdd144598 2011-02-23        kinaba: 		if( i==doc_.len(tl) && -32768<x+v.XBASE )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( p.sc(sc) )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				static const unicode* const sstr[] = { L"[EOF]", L"/" };
dcdd144598 2011-02-23        kinaba: 				static const int slen[] = { 5, 1 };
dcdd144598 2011-02-23        kinaba: 				p.SetColor( clr=CTL );
dcdd144598 2011-02-23        kinaba: 				p.StringOut( sstr[sc], slen[sc], x+v.XBASE, a.top-H );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			if( v.SYB<a.top && a.top<=v.SYE && sc==scEOL )
dcdd144598 2011-02-23        kinaba: 				Inv( a.top-H, x+v.XBASE, x+v.XBASE+p.Wc(L'/'), p );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// EOF後余白を背景色塗
dcdd144598 2011-02-23        kinaba: 	if( a.top < v.rc.bottom )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		a.left   = v.rc.left;
dcdd144598 2011-02-23        kinaba: 		a.right  = v.rc.right;
dcdd144598 2011-02-23        kinaba: 		a.bottom = v.rc.bottom;
dcdd144598 2011-02-23        kinaba: 		p.Fill( a );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }