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

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

・TinyXMLをabdevプロジェクトで使えるようにした。
・コードハイライターを汎用的に実装しなおした。syntaxファイルを読み込む仕様とした。

File size: 14.6 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( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiBegin.size() ) == 0
413 && IsStr == 0
414 && dwComment == 0 )
415 {
416 // /*
417 dwComment=12;
418 bMultiLineComment=1;
419 }
420 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentMultiEnd.size() ) == 0
421 && dwComment == 10
422 && bMultiLineComment )
423 {
424 // */
425 dwComment=3;
426 }
427
428 //単行コメント
429 if( memicmp( pBuf+i, ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.c_str(), ActiveBasic::IDE::Program::ablang->GetSyntax().commentSingle.size() ) == 0
430 && dwComment == 0
431 && IsStr == 0 )
432 {
433 // '
434 dwComment=10;
435 bMultiLineComment=0;
436 }
437
438 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
439 //単行コメント中での改行は、コメントを解除
440 if(dwComment&&bMultiLineComment==0){
441 IsStr=0;
442 dwComment=0;
443 }
444 }
445 if(dwComment!=0&&dwComment!=10) dwComment--;
446 }
447 if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){
448 //複数行に渡るコメントを考慮
449 if(pBuf[i]=='<'&&pBuf[i+1]=='!'&&pBuf[i+2]=='-'&&pBuf[i+3]=='-'&&IsStr==0&&dwComment==0){
450 dwComment=10;
451 }
452 if(pBuf[i]=='-'&&pBuf[i+1]=='-'&&pBuf[i+2]=='>'&&
453 dwComment){
454 dwComment=4;
455 }
456 if(dwComment!=0&&dwComment!=10) dwComment--;
457 }
458
459 //ハイパーリンク用下線
460 if(MdiInfo[WndNum]->pMdiTextEdit->iUnderStart<=i&&i<MdiInfo[WndNum]->pMdiTextEdit->iUnderEnd)
461 bHyperLinkUnderBar=1;
462 else bHyperLinkUnderBar=0;
463
464 if(0<=y&&y<=OnePage_CharHeight){
465 //////////////////////////////////
466 // 表示中ページでは文字単位で描画
467 //////////////////////////////////
468 //※i2に描画する文字数を格納する
469
470 NextBackColor=DefaultBackColor;
471 if(dwComment){
472 //複数行に渡るコメント
473 NextColor=tci.rgbComment;
474 }
475 else{
476 //通常カラー
477 NextColor=MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i];
478 }
479
480 if(CharRange.cpMin<=i&&i<CharRange.cpMax){
481 //選択されているバッファは反転表示する
482 NextColor=NextColor^0x00FFFFFF;
483 NextBackColor=NextBackColor^0x00FFFFFF;
484 }
485 else{
486 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
487 //カーソル行
488 NextBackColor=CaretBackColor;
489 }
490 }
491
492 if(IsDBCSLeadByte(pBuf[i])){
493 //マルチバイト文字
494 i2=2;
495 obj_dr.DrawReserve(
496 x,
497 y,
498 NextColor,
499 NextBackColor,
500 bHyperLinkUnderBar,
501 pBuf+i,i2);
502
503 i++;
504 }
505 else if(pBuf[i]=='\t'){
506 //タブ文字
507 int tab;
508 tab=pobj_nv->TabSize;
509
510 if((x-BaseX)%tab==0) i2=tab;
511 else i2=tab-(x-BaseX)%tab;
512 memset(temporary,' ',i2);
513 temporary[i2]=0;
514
515 obj_dr.DrawReserve(
516 x,
517 y,
518 NextColor,
519 NextBackColor,
520 bHyperLinkUnderBar,
521 temporary,i2);
522 }
523 else if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
524 //改行文字は1スペースだけ空白を描画しておく(反転表示をするため)
525 i2=1;
526 temporary[0]=' ';
527 temporary[1]=0;
528 obj_dr.DrawReserve(
529 x,
530 y,
531 NextColor,
532 NextBackColor,
533 bHyperLinkUnderBar,
534 temporary,i2);
535
536
537 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==y-BaseY){
538 ///////////////////////////////////////////////////////////
539 //改行コードよりも右側は白いブラシで塗りつぶす(カーソル行用)
540 ///////////////////////////////////////////////////////////
541
542 HBRUSH hTempBrush;
543
544 //カーソル行
545 hTempBrush=(HBRUSH)SelectObject(obj_dr.memdc,hCaretBackBrush);
546
547 PatBlt(obj_dr.memdc,
548 (x+i2)*font_width +iControlTabSpace,
549 y*font_height,
550 ClientRect.right-((x+i2)*font_width +iControlTabSpace),
551 font_height,
552 PATCOPY);
553
554 //カーソル行
555 SelectObject(obj_dr.memdc,hTempBrush);
556 }
557 }
558 else{
559 //通常のキャラ文字
560 i2=1;
561 obj_dr.DrawReserve(
562 x,
563 y,
564 NextColor,
565 NextBackColor,
566 bHyperLinkUnderBar,
567 pBuf+i,i2);
568 }
569 }
570 else{
571 ////////////////////////////////////////
572 // 非表示ページでは文字数の計算だけ行う
573 ////////////////////////////////////////
574 //※i2に描画する文字数を格納する
575
576 if(IsDBCSLeadByte(pBuf[i])){
577 //マルチバイト文字
578 i2=2;
579 i++;
580 }
581 else if(pBuf[i]=='\t'){
582 //タブ文字
583 int tab;
584 tab=pobj_nv->TabSize;
585
586 if((x-BaseX)%tab==0) i2=tab;
587 else i2=tab-(x-BaseX)%tab;
588 }
589 else{
590 //通常のキャラ文字(改行文字を含む)
591 i2=1;
592 }
593 }
594
595 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
596 y++;
597
598 if(MaxX<CharX) MaxX=CharX;
599
600 x=BaseX;
601 CharX=0;
602
603 i++;
604 }
605 else{
606 x+=i2;
607 CharX+=i2;
608 }
609 }
610
611 obj_dr.finish(BaseY);
612
613 DeleteObject(hCaretBackBrush);
614
615
616 //////////////////////////////////
617 // スクロールバーの範囲をセット
618 //////////////////////////////////
619
620 if(pobj_nv->bRightTurn){
621 MaxX=0;
622 }
623
624 ResetScrollbar(WndNum,MaxX,(-BaseY)+y);
625}
Note: See TracBrowser for help on using the repository browser.