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

Last change on this file since 475 was 475, checked in by dai_9181, 16 years ago

構成管理を変更中・・・(いったんコミット)

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 CFileBreakPoint *pobj_FileBreakPoint=0;
193 if(ProjectInfo.name[0]){
194 pobj_FileBreakPoint=
195 ProjectInfo.pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum].path);
196 }
197 else{
198 extern CDBBreakPoint *pobj_DBBreakPoint;
199 pobj_FileBreakPoint=pobj_DBBreakPoint->EnumLines(MdiInfo[m_WndNum].path);
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 extern MDIINFO MdiInfo[MAX_WNDNUM];
269 int i,i2;
270 int x,y;
271 int BaseX,BaseY,CharX;
272 char *pBuf,temporary[255];
273 HWND hEdit;
274
275
276 //背景モード、カラーの設定
277 COLORREF DefaultBackColor,CaretBackColor;
278 DefaultBackColor=tci.rgbBackground;
279
280 RECT ClientRect;
281 hEdit=GetWindow(MdiInfo[WndNum].hwnd,GW_CHILD);
282 GetClientRect(hEdit,&ClientRect);
283
284 //エディタ画面左端のコントロールタブ
285 int iControlTabSpace;
286 int iLineNumberTextCount;
287 iControlTabSpace=MdiInfo[WndNum].pMdiTextEdit->iWidth_ControlTabSpace;
288 iLineNumberTextCount=MdiInfo[WndNum].pMdiTextEdit->iLineNumberTextCount;
289
290 //一ページ中に表示できる行数を取得
291 int OnePage_CharHeight;
292 OnePage_CharHeight=(ClientRect.bottom/font_height)+1;
293
294 //描画用クラス
295 CDrawReserve obj_dr(
296 WndNum,
297 hdc,
298 ClientRect.right-ClientRect.left,ClientRect.bottom-ClientRect.top,
299 iControlTabSpace,
300 OnePage_CharHeight,
301 iLineNumberTextCount);
302
303
304 //テキストバッファをコード内で参照しやすいようにポインタ変数を利用する
305 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
306
307 //選択範囲を取得
308 CHARRANGE CharRange;
309 TextEdit_GetSel(WndNum,&CharRange);
310
311 //ベース描画ポジションを取得(文字単位)
312 BaseX=0;
313 BaseY=0;
314 GetScrollBaseCaretPos(WndNum,&BaseX,&BaseY);
315
316 if(pobj_nv->bEditor_CaretLine_BackGround){
317 //カーソル行の色を変える
318 CaretBackColor=tci.rgbCursorBack;
319 }
320 else{
321 //カーソル行の色を変えない
322 CaretBackColor=tci.rgbBackground;
323 }
324 HBRUSH hCaretBackBrush;
325 hCaretBackBrush=CreateSolidBrush(CaretBackColor);
326
327 BOOL IsStr=0;
328 DWORD dwComment=0;
329 BOOL bMultiLineComment;
330 COLORREF NextColor,NextBackColor;
331 int MaxX=0;
332 x=BaseX;
333 y=BaseY;
334 CharX=0; //左端から何文字目かを示す
335 int bHyperLinkUnderBar=0; //ハイパーリンク用下線の表示スイッチ
336 for(i=0;;i++){
337 if(pBuf[i]=='\0'){
338 if(0<=y&&y<=OnePage_CharHeight){
339 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==y-BaseY){
340 ////////////////////////////////////
341 // カーソル行では余白を塗りつぶす
342 ////////////////////////////////////
343
344 HBRUSH hTempBrush;
345 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
346
347 //終端コードよりも右側はブラシで塗りつぶす
348 PatBlt(obj_dr.memdc,
349 x*font_width +iControlTabSpace,
350 y*font_height,
351 ClientRect.right-(x*font_width +iControlTabSpace),
352 font_height,
353 PATCOPY);
354
355 //カーソル行
356 SelectObject(obj_dr.memdc,hTempBrush);
357 }
358
359 //行番号が末端行にも表示されるようにするために描画予約を行う
360 obj_dr.DrawReserve(
361 x,
362 y,
363 NULL,
364 NULL,
365 bHyperLinkUnderBar,
366 "",0);
367 }
368
369 if(MaxX<CharX) MaxX=CharX;
370
371 break;
372 }
373
374 if(IsRightTurn(pBuf,i,x)){
375 /////////////////
376 // 自動折り返し
377 /////////////////
378
379 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==y-BaseY){
380 ///////////////////////////////////////////////////////////
381 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
382 ///////////////////////////////////////////////////////////
383
384 HBRUSH hTempBrush;
385
386 //カーソル行
387 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
388
389 PatBlt(obj_dr.memdc,
390 x*font_width +iControlTabSpace,
391 y*font_height,
392 ClientRect.right-(x*font_width +iControlTabSpace),
393 font_height,
394 PATCOPY);
395
396 //カーソル行
397 SelectObject(obj_dr.memdc,hTempBrush);
398 }
399
400 y++;
401
402 x=BaseX;
403 CharX=0;
404 i--;
405 continue;
406 }
407
408 if(MdiInfo[WndNum].DocType==WNDTYPE_BASIC){
409
410 if(pBuf[i]=='\"'&&dwComment==0) IsStr^=1;
411
412 //複数行に渡るコメントを考慮
413 if(pBuf[i]=='/'&&pBuf[i+1]=='*'&&IsStr==0&&dwComment==0){
414 dwComment=12;
415 bMultiLineComment=1;
416 }
417 if(pBuf[i]=='*'&&pBuf[i+1]=='/'&&
418 dwComment==10&&bMultiLineComment){
419 dwComment=3;
420 }
421
422 //単行コメント
423 if(pBuf[i]=='\''&&dwComment==0&&IsStr==0){
424 dwComment=10;
425 bMultiLineComment=0;
426 }
427
428 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
429 //単行コメント中での改行は、コメントを解除
430 if(dwComment&&bMultiLineComment==0){
431 IsStr=0;
432 dwComment=0;
433 }
434 }
435 if(dwComment!=0&&dwComment!=10) dwComment--;
436 }
437 if(MdiInfo[WndNum].DocType==WNDTYPE_HTML){
438 //複数行に渡るコメントを考慮
439 if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){
440 dwComment=10;
441 }
442 if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&&
443 dwComment){
444 dwComment=4;
445 }
446 if(dwComment!=0&&dwComment!=10) dwComment--;
447 }
448
449 //ハイパーリンク用下線
450 if(MdiInfo[WndNum].pMdiTextEdit->iUnderStart<=i&&i<MdiInfo[WndNum].pMdiTextEdit->iUnderEnd)
451 bHyperLinkUnderBar=1;
452 else bHyperLinkUnderBar=0;
453
454 if(0<=y&&y<=OnePage_CharHeight){
455 //////////////////////////////////
456 // 表示中ページでは文字単位で描画
457 //////////////////////////////////
458 //※i2に描画する文字数を格納する
459
460 NextBackColor=DefaultBackColor;
461 if(dwComment){
462 //複数行に渡るコメント
463 NextColor=tci.rgbComment;
464 }
465 else{
466 //通常カラー
467 NextColor=MdiInfo[WndNum].pMdiTextEdit->pColorRef[i];
468 }
469
470 if(CharRange.cpMin<=i&&i<CharRange.cpMax){
471 //選択されているバッファは反転表示する
472 NextColor=NextColor^0x00FFFFFF;
473 NextBackColor=NextBackColor^0x00FFFFFF;
474 }
475 else{
476 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==y-BaseY){
477 //カーソル行
478 NextBackColor=CaretBackColor;
479 }
480 }
481
482 if(IsDBCSLeadByte(pBuf[i])){
483 //マルチバイト文字
484 i2=2;
485 obj_dr.DrawReserve(
486 x,
487 y,
488 NextColor,
489 NextBackColor,
490 bHyperLinkUnderBar,
491 pBuf+i,i2);
492
493 i++;
494 }
495 else if(pBuf[i]=='\t'){
496 //タブ文字
497 int tab;
498 tab=pobj_nv->TabSize;
499
500 if((x-BaseX)%tab==0) i2=tab;
501 else i2=tab-(x-BaseX)%tab;
502 memset(temporary,' ',i2);
503 temporary[i2]=0;
504
505 obj_dr.DrawReserve(
506 x,
507 y,
508 NextColor,
509 NextBackColor,
510 bHyperLinkUnderBar,
511 temporary,i2);
512 }
513 else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
514 //改行文字は1スペースだけ空白を描画しておく(反転表示をするため)
515 i2=1;
516 temporary[0]=' ';
517 temporary[1]=0;
518 obj_dr.DrawReserve(
519 x,
520 y,
521 NextColor,
522 NextBackColor,
523 bHyperLinkUnderBar,
524 temporary,i2);
525
526
527 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==y-BaseY){
528 ///////////////////////////////////////////////////////////
529 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
530 ///////////////////////////////////////////////////////////
531
532 HBRUSH hTempBrush;
533
534 //カーソル行
535 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
536
537 PatBlt(obj_dr.memdc,
538 (x+i2)*font_width +iControlTabSpace,
539 y*font_height,
540 ClientRect.right-((x+i2)*font_width +iControlTabSpace),
541 font_height,
542 PATCOPY);
543
544 //カーソル行
545 SelectObject(obj_dr.memdc,hTempBrush);
546 }
547 }
548 else{
549 //通常のキャラ文字
550 i2=1;
551 obj_dr.DrawReserve(
552 x,
553 y,
554 NextColor,
555 NextBackColor,
556 bHyperLinkUnderBar,
557 pBuf+i,i2);
558 }
559 }
560 else{
561 ////////////////////////////////////////
562 // 非表示ページでは文字数の計算だけ行う
563 ////////////////////////////////////////
564 //※i2に描画する文字数を格納する
565
566 if(IsDBCSLeadByte(pBuf[i])){
567 //マルチバイト文字
568 i2=2;
569 i++;
570 }
571 else if(pBuf[i]=='\t'){
572 //タブ文字
573 int tab;
574 tab=pobj_nv->TabSize;
575
576 if((x-BaseX)%tab==0) i2=tab;
577 else i2=tab-(x-BaseX)%tab;
578 }
579 else{
580 //通常のキャラ文字(改行文字を含む)
581 i2=1;
582 }
583 }
584
585 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
586 y++;
587
588 if(MaxX<CharX) MaxX=CharX;
589
590 x=BaseX;
591 CharX=0;
592
593 i++;
594 }
595 else{
596 x+=i2;
597 CharX+=i2;
598 }
599 }
600
601 obj_dr.finish(BaseY);
602
603 DeleteObject(hCaretBackBrush);
604
605
606 //////////////////////////////////
607 // スクロールバーの範囲をセット
608 //////////////////////////////////
609
610 if(pobj_nv->bRightTurn){
611 MaxX=0;
612 }
613
614 ResetScrollbar(WndNum,MaxX,(-BaseY)+y);
615}
Note: See TracBrowser for help on using the repository browser.