source: dev/trunk/abdev/ProjectEditor/DrawBuffer.cpp@ 403

Last change on this file since 403 was 24, checked in by dai_9181, 18 years ago

保存されていないドキュメントのタブに(*)をつける機能に対応。
MDITEXTEDITINFOをCMdiTextEditに変更。今後、オブジェクト指向化を進める。

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