source: dev/trunk/ab5.0/abdev/abdev/DrawBuffer.cpp @ 655

Last change on this file since 655 was 655, checked in by dai_9181, 15 years ago

FileManager周りをリファクタリング

File size: 14.0 KB
Line 
1#include "stdafx.h"
2
3#include "Common.h"
4
5extern HFONT hFont_TextEdit;
6extern int font_width,font_height;
7
8class CDrawReserve{
9    int x,y;
10    COLORREF NowColor,NowBackColor;
11    int bNowUnder;
12    char *lpszBuffer;
13    int length;
14    int m_WndNum;
15    HDC hdc;
16    HBITMAP hMemBmp,hOldBitmap;
17    HFONT hOldFont;
18    SIZE ClientSize;
19    int iControlTabSpace;
20    int iOnePage_CharHeight;
21    int iLineNumberTextCount;
22    int iMax_OneLine_TextLength;
23public:
24    HDC memdc;
25    CDrawReserve(int WndNum,HDC _hDC,int cx,int cy,int ctrl_tab_space,int nMaxOnePageChar,int linenum_textcount){
26        m_WndNum=WndNum;
27        x=-1;
28        y=-1;
29        bNowUnder=0;
30        hdc=_hDC;
31        ClientSize.cx=cx;
32        ClientSize.cy=cy;
33        iControlTabSpace=ctrl_tab_space;
34        iOnePage_CharHeight=nMaxOnePageChar;
35        iMax_OneLine_TextLength=cx/font_width+1;
36        iLineNumberTextCount=linenum_textcount;
37        memdc=CreateCompatibleDC(hdc);
38        hMemBmp=CreateCompatibleBitmap(hdc,cx,cy);
39        hOldBitmap=(HBITMAP)SelectObject(memdc,hMemBmp);
40
41        //背景色でメモリ画面を初期化
42        HBRUSH hBrush,hOldBrush;
43        hBrush=CreateSolidBrush(tci.rgbBackground);
44        hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
45        PatBlt(memdc,0,0,cx,cy,PATCOPY);
46        DeleteObject(hBrush);
47
48        //背景ビットマップ
49#ifdef THETEXT
50        if(pobj_DBTheme->hBackBmp){
51            HDC memdc2;
52            memdc2=CreateCompatibleDC(memdc);
53            SelectObject(memdc2,pobj_DBTheme->hBackBmp);
54            BitBlt(memdc,
55                cx-(pobj_DBTheme->sizeBackBmp.cx),
56                cy-(pobj_DBTheme->sizeBackBmp.cy),
57                pobj_DBTheme->sizeBackBmp.cx,pobj_DBTheme->sizeBackBmp.cy,
58                memdc2,0,0,SRCCOPY);
59            DeleteDC(memdc2);
60        }
61#endif
62
63        //フォントを設定
64        extern HFONT hFont_TextEdit;
65        hOldFont=(HFONT)SelectObject(memdc,hFont_TextEdit);
66
67        lpszBuffer=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);
68        length=0;
69    }
70    ~CDrawReserve(){
71        SelectObject(memdc,hOldBitmap);
72        DeleteObject(hMemBmp);
73
74        SelectObject(memdc,hOldFont);
75
76        DeleteDC(memdc);
77
78        HeapDefaultFree(lpszBuffer);
79    }
80
81    void draw(){
82        if(length==0) return;
83        SetTextColor(memdc,NowColor);
84        if(NowBackColor==tci.rgbBackground){
85            SetBkMode(memdc,TRANSPARENT);
86        }
87        else{
88            SetBkMode(memdc,OPAQUE);
89            SetBkColor(memdc,NowBackColor);
90        }
91
92        HFONT hBeforeFont;
93        if(bNowUnder){
94            //下線付きフォントに設定
95            extern HFONT hFont_HyperLink_TextEdit;
96            hBeforeFont=(HFONT)SelectObject(memdc,hFont_HyperLink_TextEdit);
97        }
98
99        int offset=0;
100        if(x<0){
101            offset=-x;
102
103            //左端の全角文字の文字化けを避けるために10バイトの余裕を作る
104            offset-=10;
105            if(offset<0) offset=0;
106
107            length-=offset;
108            if(length<0) return;
109        }
110
111        if(length>iMax_OneLine_TextLength+10){
112            length=iMax_OneLine_TextLength+10;
113        }
114
115        int i;
116        int *lpDxWidths;
117        lpDxWidths=(int *)malloc((length+1)*sizeof(int));
118        for(i=0;i<length+1;i++){
119            lpDxWidths[i]=font_width;
120        }
121        ExtTextOut(memdc,
122            (x+offset)*(font_width)     +iControlTabSpace,
123            y*font_height,
124            0,NULL,
125            lpszBuffer+offset,length,
126            lpDxWidths);
127
128        if(bNowUnder){
129            SelectObject(memdc,hBeforeFont);
130        }
131
132        free(lpDxWidths);
133    }
134
135    void DrawReserve(int nXStart,int nYStart,COLORREF NextColor,COLORREF NextBackColor,BOOL bUnder,LPSTR lpString,int cbString){
136        if(nYStart!=y || NextColor!=NowColor || NextBackColor!=NowBackColor || bUnder!=bNowUnder){
137            //描画
138            draw();
139
140            x=nXStart;
141            y=nYStart;
142            NowColor=NextColor;
143            NowBackColor=NextBackColor;
144            bNowUnder=bUnder;
145
146            lpszBuffer[0]=0;
147            length=0;
148        }
149
150        //予約
151        lpszBuffer=(char *)HeapReAlloc(hHeap,0,lpszBuffer,length+cbString+1);
152        memcpy(lpszBuffer+length,lpString,cbString);
153        length+=cbString;
154        lpszBuffer[length]=0;
155    }
156
157    void finish(int BaseY){
158        draw();
159
160        HBRUSH hBrush,hOldBrush;
161        if(pobj_nv->bEditor_LineNumber){
162            hBrush=CreateSolidBrush(RGB(220,220,220));
163            hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
164
165
166            /////////////////////////////////////////////////////
167            // エディタ画面左端のコントロールタブの行番号を描画
168            /////////////////////////////////////////////////////
169
170            //灰色で塗りつぶす
171            PatBlt(memdc,
172                0,
173                0,
174                iControlTabSpace,
175                ClientSize.cy,
176                PATCOPY);
177
178            extern HFONT hFont_LineNumber;
179            int LineNumberFontHeight;
180
181            HFONT hOldFont;
182            hOldFont=(HFONT)SelectObject(memdc,hFont_LineNumber);
183            SetTextColor(memdc,RGB(60,60,60));
184            SetBkColor(memdc,RGB(220,220,220));
185
186            SIZE size;
187            GetTextExtentPoint32(memdc,"A",1,&size);
188            LineNumberFontHeight=size.cy;
189
190
191            //ブレークポイントの描画を準備
192            BreakPointsPerFile *pobj_FileBreakPoint=0;
193            if( projectInfo.IsOpened() ){
194                pobj_FileBreakPoint=
195                    projectInfo.pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str());
196            }
197            else{
198                extern CDBBreakPoint *pobj_DBBreakPoint;
199                pobj_FileBreakPoint=pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum]->path.c_str());
200            }
201
202
203            int i,i2;
204            char temporary[255],temp2[255];
205            if(y<iOnePage_CharHeight) i2=y;
206            else i2=iOnePage_CharHeight;
207            for(i=0;i<=i2;i++){
208
209                BOOL bBreakPoint;
210                bBreakPoint=0;
211                if(pobj_FileBreakPoint){
212                    if(pobj_FileBreakPoint->check(i-BaseY)){
213                        bBreakPoint=1;
214                    }
215                }
216
217                if(bBreakPoint){
218                    DrawIconEx(memdc,3,i*font_height+(font_height-16)/2,
219                        (HICON)LoadImage(hIconResInst,MAKEINTRESOURCE(IDI_BREAKPOINT_FLAG),IMAGE_ICON,16,16,LR_SHARED),
220                        16,16,0,NULL,DI_NORMAL);
221                }
222                else{
223                    sprintf(temp2,"%%%dd:",iLineNumberTextCount);
224                    sprintf(temporary,temp2,(i-BaseY)+1);
225
226                    TextOut(memdc,
227                        3,
228                        i*font_height+(font_height-LineNumberFontHeight)/2,
229                        temporary,
230                        lstrlen(temporary));
231                }
232            }
233
234            SelectObject(memdc,hOldFont);
235
236
237            //ブラシを破棄
238            SelectObject(memdc,hOldBrush);
239            DeleteObject(hBrush);
240        }
241        else{
242            ////////////////////////////////////////////
243            // エディタ画面左端のコントロールタブを描画
244            // ※行番号は非表示
245            ////////////////////////////////////////////
246
247            hBrush=CreateSolidBrush(RGB(220,220,220));
248            hOldBrush=(HBRUSH)SelectObject(memdc,hBrush);
249
250            PatBlt(memdc,
251                0,
252                0,
253                iControlTabSpace,
254                ClientSize.cy,
255                PATCOPY);
256
257            SelectObject(memdc,hOldBrush);
258            DeleteObject(hBrush);
259        }
260
261
262        //メモリDCの内容を画面に描画
263        BitBlt(hdc,0,0,ClientSize.cx,ClientSize.cy,memdc,0,0,SRCCOPY);
264    }
265};
266
267void TextEdit_DrawBuffer(HDC hdc,int WndNum){
268    int i,i2;
269    int x,y;
270    int BaseX,BaseY,CharX;
271    char *pBuf,temporary[255];
272    HWND hEdit;
273
274
275    //背景モード、カラーの設定
276    COLORREF DefaultBackColor,CaretBackColor;
277    DefaultBackColor=tci.rgbBackground;
278
279    RECT ClientRect;
280    hEdit=GetWindow(MdiInfo[WndNum]->hwnd,GW_CHILD);
281    GetClientRect(hEdit,&ClientRect);
282
283    //エディタ画面左端のコントロールタブ
284    int iControlTabSpace;
285    int iLineNumberTextCount;
286    iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
287    iLineNumberTextCount=MdiInfo[WndNum]->pMdiTextEdit->iLineNumberTextCount;
288
289    //一ページ中に表示できる行数を取得
290    int OnePage_CharHeight;
291    OnePage_CharHeight=(ClientRect.bottom/font_height)+1;
292
293    //描画用クラス
294    CDrawReserve obj_dr(
295        WndNum,
296        hdc,
297        ClientRect.right-ClientRect.left,ClientRect.bottom-ClientRect.top,
298        iControlTabSpace,
299        OnePage_CharHeight,
300        iLineNumberTextCount);
301
302
303    //テキストバッファをコード内で参照しやすいようにポインタ変数を利用する
304    pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
305
306    //選択範囲を取得
307    CHARRANGE CharRange;
308    TextEdit_GetSel(WndNum,&CharRange);
309
310    //ベース描画ポジションを取得(文字単位)
311    BaseX=0;
312    BaseY=0;
313    GetScrollBaseCaretPos(MdiInfo[WndNum],&BaseX,&BaseY);
314
315    if(pobj_nv->bEditor_CaretLine_BackGround){
316        //カーソル行の色を変える
317        CaretBackColor=tci.rgbCursorBack;
318    }
319    else{
320        //カーソル行の色を変えない
321        CaretBackColor=tci.rgbBackground;
322    }
323    HBRUSH hCaretBackBrush;
324    hCaretBackBrush=CreateSolidBrush(CaretBackColor);
325
326    BOOL IsStr=0;
327    DWORD dwComment=0;
328    BOOL bMultiLineComment;
329    COLORREF NextColor,NextBackColor;
330    int MaxX=0;
331    x=BaseX;
332    y=BaseY;
333    CharX=0;    //左端から何文字目かを示す
334    int bHyperLinkUnderBar=0;   //ハイパーリンク用下線の表示スイッチ
335    for(i=0;;i++){
336        if(pBuf[i]=='\0'){
337            if(0<=y&&y<=OnePage_CharHeight){
338                if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
339                    ////////////////////////////////////
340                    // カーソル行では余白を塗りつぶす
341                    ////////////////////////////////////
342
343                    HBRUSH hTempBrush;
344                    hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
345
346                    //終端コードよりも右側はブラシで塗りつぶす
347                    PatBlt(obj_dr.memdc,
348                        x*font_width     +iControlTabSpace,
349                        y*font_height,
350                        ClientRect.right-(x*font_width     +iControlTabSpace),
351                        font_height,
352                        PATCOPY);
353
354                    //カーソル行
355                    SelectObject(obj_dr.memdc,hTempBrush);
356                }
357
358                //行番号が末端行にも表示されるようにするために描画予約を行う
359                obj_dr.DrawReserve(
360                    x,
361                    y,
362                    NULL,
363                    NULL,
364                    bHyperLinkUnderBar,
365                    "",0);
366            }
367
368            if(MaxX<CharX) MaxX=CharX;
369
370            break;
371        }
372
373        if(IsRightTurn(pBuf,i,x)){
374            /////////////////
375            // 自動折り返し
376            /////////////////
377
378            if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
379                ///////////////////////////////////////////////////////////
380                //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
381                ///////////////////////////////////////////////////////////
382
383                HBRUSH hTempBrush;
384
385                //カーソル行
386                hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
387
388                PatBlt(obj_dr.memdc,
389                    x*font_width     +iControlTabSpace,
390                    y*font_height,
391                    ClientRect.right-(x*font_width     +iControlTabSpace),
392                    font_height,
393                    PATCOPY);
394
395                //カーソル行
396                SelectObject(obj_dr.memdc,hTempBrush);
397            }
398
399            y++;
400
401            x=BaseX;
402            CharX=0;
403            i--;
404            continue;
405        }
406
407        if(MdiInfo[WndNum]->DocType==WNDTYPE_BASIC){
408
409            if(pBuf[i]=='\"'&&dwComment==0) IsStr^=1;
410
411            //複数行に渡るコメントを考慮
412            if(pBuf[i]=='/'&&pBuf[i+1]=='*'&&IsStr==0&&dwComment==0){
413                dwComment=12;
414                bMultiLineComment=1;
415            }
416            if(pBuf[i]=='*'&&pBuf[i+1]=='/'&&
417                dwComment==10&&bMultiLineComment){
418                dwComment=3;
419            }
420
421            //単行コメント
422            if(pBuf[i]=='\''&&dwComment==0&&IsStr==0){
423                dwComment=10;
424                bMultiLineComment=0;
425            }
426
427            if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
428                //単行コメント中での改行は、コメントを解除
429                if(dwComment&&bMultiLineComment==0){
430                    IsStr=0;
431                    dwComment=0;
432                }
433            }
434            if(dwComment!=0&&dwComment!=10) dwComment--;
435        }
436        if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){
437            //複数行に渡るコメントを考慮
438            if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){
439                dwComment=10;
440            }
441            if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&&
442                dwComment){
443                dwComment=4;
444            }
445            if(dwComment!=0&&dwComment!=10) dwComment--;
446        }
447
448        //ハイパーリンク用下線
449        if(MdiInfo[WndNum]->pMdiTextEdit->iUnderStart<=i&&i<MdiInfo[WndNum]->pMdiTextEdit->iUnderEnd)
450            bHyperLinkUnderBar=1;
451        else bHyperLinkUnderBar=0;
452
453        if(0<=y&&y<=OnePage_CharHeight){
454            //////////////////////////////////
455            // 表示中ページでは文字単位で描画
456            //////////////////////////////////
457            //※i2に描画する文字数を格納する
458
459            NextBackColor=DefaultBackColor;
460            if(dwComment){
461                //複数行に渡るコメント
462                NextColor=tci.rgbComment;
463            }
464            else{
465                //通常カラー
466                NextColor=MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i];
467            }
468
469            if(CharRange.cpMin<=i&&i<CharRange.cpMax){
470                //選択されているバッファは反転表示する
471                NextColor=NextColor^0x00FFFFFF;
472                NextBackColor=NextBackColor^0x00FFFFFF;
473            }
474            else{
475                if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
476                    //カーソル行
477                    NextBackColor=CaretBackColor;
478                }
479            }
480
481            if(IsDBCSLeadByte(pBuf[i])){
482                //マルチバイト文字
483                i2=2;
484                obj_dr.DrawReserve(
485                    x,
486                    y,
487                    NextColor,
488                    NextBackColor,
489                    bHyperLinkUnderBar,
490                    pBuf+i,i2);
491
492                i++;
493            }
494            else if(pBuf[i]=='\t'){
495                //タブ文字
496                int tab;
497                tab=pobj_nv->TabSize;
498
499                if((x-BaseX)%tab==0) i2=tab;
500                else i2=tab-(x-BaseX)%tab;
501                memset(temporary,' ',i2);
502                temporary[i2]=0;
503
504                obj_dr.DrawReserve(
505                    x,
506                    y,
507                    NextColor,
508                    NextBackColor,
509                    bHyperLinkUnderBar,
510                    temporary,i2);
511            }
512            else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
513                //改行文字は1スペースだけ空白を描画しておく(反転表示をするため)
514                i2=1;
515                temporary[0]=' ';
516                temporary[1]=0;
517                obj_dr.DrawReserve(
518                    x,
519                    y,
520                    NextColor,
521                    NextBackColor,
522                    bHyperLinkUnderBar,
523                    temporary,i2);
524
525
526                if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
527                    ///////////////////////////////////////////////////////////
528                    //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
529                    ///////////////////////////////////////////////////////////
530
531                    HBRUSH hTempBrush;
532
533                    //カーソル行
534                    hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
535
536                    PatBlt(obj_dr.memdc,
537                        (x+i2)*font_width     +iControlTabSpace,
538                        y*font_height,
539                        ClientRect.right-((x+i2)*font_width     +iControlTabSpace),
540                        font_height,
541                        PATCOPY);
542
543                    //カーソル行
544                    SelectObject(obj_dr.memdc,hTempBrush);
545                }
546            }
547            else{
548                //通常のキャラ文字
549                i2=1;
550                obj_dr.DrawReserve(
551                    x,
552                    y,
553                    NextColor,
554                    NextBackColor,
555                    bHyperLinkUnderBar,
556                    pBuf+i,i2);
557            }
558        }
559        else{
560            ////////////////////////////////////////
561            // 非表示ページでは文字数の計算だけ行う
562            ////////////////////////////////////////
563            //※i2に描画する文字数を格納する
564
565            if(IsDBCSLeadByte(pBuf[i])){
566                //マルチバイト文字
567                i2=2;
568                i++;
569            }
570            else if(pBuf[i]=='\t'){
571                //タブ文字
572                int tab;
573                tab=pobj_nv->TabSize;
574
575                if((x-BaseX)%tab==0) i2=tab;
576                else i2=tab-(x-BaseX)%tab;
577            }
578            else{
579                //通常のキャラ文字(改行文字を含む)
580                i2=1;
581            }
582        }
583
584        if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
585            y++;
586
587            if(MaxX<CharX) MaxX=CharX;
588
589            x=BaseX;
590            CharX=0;
591
592            i++;
593        }
594        else{
595            x+=i2;
596            CharX+=i2;
597        }
598    }
599
600    obj_dr.finish(BaseY);
601
602    DeleteObject(hCaretBackBrush);
603
604
605    //////////////////////////////////
606    // スクロールバーの範囲をセット
607    //////////////////////////////////
608
609    if(pobj_nv->bRightTurn){
610        MaxX=0;
611    }
612
613    ResetScrollbar(WndNum,MaxX,(-BaseY)+y);
614}
Note: See TracBrowser for help on using the repository browser.