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: }