Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10639 - (hide annotations) (download) (as text)
Fri Mar 17 14:35:30 2023 UTC (12 months, 3 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 139403 byte(s)
文字消去時、マウス選択領域を選択状態で描画(文字色反転表示)するようにした

- マウス選択領域の文字を消去したとき、選択状態を維持したまま描画
- 従来
  - マウス選択領域にかかっていても無条件に背景色(背景画像)で描画
  - 表示上選択領域がなくなるように見える
  - 内部的には選択領域が存在している
- 変更したシーケンス
  - EL (カーソル行の文字を消去)
  - ECH (カーソル位置から Ps 文字を消す)
  - ED 0 (カーソル位置から画面末尾までを消去する)
  - ED 1 (画面先頭からカーソル位置までを消去する)
- 文字消去ではなくバッファの内容を描画するようにした(buffer.c)
  - 空白(スペース)が書かれているバッファを描画 =消去
  - マウス選択領域を考慮して描画される
- 使用しなくなった文字消去(背景描画)専用関数削除(vtdisp.c,h)
- 変数 Selected を static に変更(buffer.c,h)

ticket 47524
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3 nmaya 9048 * (C) 2004- TeraTerm Project
4 doda 6806 * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, scroll buffer routines */
31    
32     #include "teraterm.h"
33     #include <string.h>
34 yutakapon 4707 #include <stdio.h>
35 doda 8445 #include <windows.h>
36     #define _CRTDBG_MAP_ALLOC
37     #include <crtdbg.h>
38     #include <assert.h>
39 maya 3227
40 doda 8445 #include "tttypes.h"
41 maya 3227 #include "ttwinman.h"
42     #include "teraprn.h"
43     #include "vtdisp.h"
44     #include "telnet.h"
45     #include "ttplug.h" /* TTPLUG */
46 doda 8445 #include "codeconv.h"
47     #include "unicode.h"
48 maya 3227 #include "buffer.h"
49 zmatsuo 8584 #include "asprintf.h"
50 zmatsuo 8825 #include "ttcstd.h"
51 maya 3227
52 zmatsuo 10354 #define ENABLE_CELL_INDEX 0
53    
54 doda 8445 // �o�b�t�@�������p1������������
55     typedef struct {
56     char32_t u32;
57     char32_t u32_last;
58 zmatsuo 8766 char WidthProperty; // 'W' or 'F' or 'H' or 'A' or 'n'(Narrow) or 'N'(Neutual) (����������)
59 zmatsuo 10308 char cell; // ������cell�� 1/2/3+=���p,�S�p,3����
60     // 2�����������A����������������padding��cell-1������
61 doda 8445 char Padding; // TRUE = �S�p�������l���� or �s�����l����
62     char Emoji; // TRUE = �G����
63 zmatsuo 8585 unsigned char CombinationCharCount16; // charactor count
64     unsigned char CombinationCharSize16; // buffer size
65     unsigned char CombinationCharCount32;
66     unsigned char CombinationCharSize32;
67 doda 8445 wchar_t *pCombinationChars16;
68     char32_t *pCombinationChars32;
69     wchar_t wc2[2];
70 zmatsuo 8741 unsigned char fg;
71     unsigned char bg;
72 zmatsuo 8742 unsigned char attr;
73     unsigned char attr2;
74 zmatsuo 8744 unsigned short ansi_char;
75 zmatsuo 10354 #if ENABLE_CELL_INDEX
76     int idx; // �Z����������
77     #endif
78 doda 8445 } buff_char_t;
79    
80 maya 3227 #define BuffXMax TermWidthMax
81     //#define BuffYMax 100000
82     //#define BuffSizeMax 8000000
83     // �X�N���[���o�b�t�@�����������g�� (2004.11.28 yutaka)
84     #define BuffYMax 500000
85     #define BuffSizeMax (BuffYMax * 80)
86    
87 zmatsuo 10354 // 1�������������R���r�l�[�V�����o�b�t�@�����T�C�Y
88 zmatsuo 9404 #define MAX_CHAR_SIZE 100
89    
90 maya 3227 // status line
91 doda 6435 int StatusLine; //0: none 1: shown
92 doda 5324 /* top, bottom, left & right margin */
93     int CursorTop, CursorBottom, CursorLeftM, CursorRightM;
94 zmatsuo 10639 static BOOL Selected; // TRUE=�����I�����s����������
95     static BOOL Selecting;
96 maya 3227 BOOL Wrap;
97    
98     static WORD TabStops[256];
99     static int NTabStops;
100    
101     static WORD BuffLock = 0;
102    
103 zmatsuo 8739 static buff_char_t *CodeBuffW;
104 maya 3227 static LONG LinePtr;
105     static LONG BufferSize;
106     static int NumOfLinesInBuff;
107     static int BuffStartAbs, BuffEndAbs;
108 doda 8400 static POINT SelectStart, SelectStartTmp, SelectEnd, SelectEndOld;
109     static DWORD SelectStartTime;
110 maya 3227 static BOOL BoxSelect;
111     static POINT DblClkStart, DblClkEnd;
112    
113 doda 8445 // �`��
114     static int StrChangeStart; // �`���J�n X (Y=CursorY)
115     static int StrChangeCount; // �`���L�����N�^��(���p�P��),0�������`����������������
116 zmatsuo 8748 static BOOL UseUnicodeApi;
117 maya 3227
118     static BOOL SeveralPageSelect; // add (2005.5.15 yutaka)
119    
120     static TCharAttr CurCharAttr;
121    
122 doda 8445 static char *SaveBuff = NULL;
123     static int SaveBuffX;
124     static int SaveBuffY;
125 doda 3743
126 zmatsuo 8770 // ANSI�\���p����������������CodePage
127     static int CodePage = 932;
128    
129 doda 8445 static void BuffDrawLineI(int DrawX, int DrawY, int SY, int IStart, int IEnd);
130 zmatsuo 9040 static void BuffDrawLineIPrn(int SY, int IStart, int IEnd);
131 doda 8445
132 zmatsuo 10354 /**
133     * buff_char_t �� rel�Z����������
134     *
135     * @param CodeBuffW_ �����o�b�t�@�������|�C���^
136     * @param BufferSize_ �����o�b�t�@���T�C�Y(buff_char_t�P��)
137     * @param p �����������|�C���^
138     * @param rel ������
139     * @retval ���������|�C���^
140     */
141     static buff_char_t *GetPtrRel(buff_char_t *CodeBuffW_, size_t BufferSize_, buff_char_t *p, int rel)
142     {
143     ptrdiff_t idx = (ptrdiff_t)(p - CodeBuffW_) + rel;
144     for (;;) {
145     if (idx < 0) {
146     idx += BufferSize_;
147     }
148     else if (idx >= (ptrdiff_t)BufferSize_) {
149     idx -= BufferSize_;
150     }
151     else {
152     break;
153     }
154     }
155     p = &CodeBuffW_[(int)idx];
156     return p;
157     }
158    
159     static void FreeCombinationBuf(buff_char_t *b)
160     {
161     if (b->pCombinationChars16 != NULL) {
162     free(b->pCombinationChars16);
163     b->pCombinationChars16 = NULL;
164     }
165     b->CombinationCharSize16 = 0;
166     b->CombinationCharCount16 = 0;
167    
168     if (b->pCombinationChars32 != NULL) {
169     free(b->pCombinationChars32);
170     b->pCombinationChars32 = NULL;
171     }
172     b->CombinationCharSize32 = 0;
173     b->CombinationCharCount32 = 0;
174     }
175    
176     static void DupCombinationBuf(buff_char_t *b)
177     {
178     size_t size;
179    
180     size = b->CombinationCharSize16;
181     if (size > 0) {
182     wchar_t *new_buf = malloc(sizeof(wchar_t) * size);
183     memcpy(new_buf, b->pCombinationChars16, sizeof(wchar_t) * size);
184     b->pCombinationChars16 = new_buf;
185     }
186     size = b->CombinationCharSize32;
187     if (size > 0) {
188     char32_t *new_buf = malloc(sizeof(char32_t) * size);
189     memcpy(new_buf, b->pCombinationChars32, sizeof(char32_t) * size);
190     b->pCombinationChars32 = new_buf;
191     }
192     }
193    
194     static void CopyCombinationBuf(buff_char_t *dest, const buff_char_t *src)
195     {
196     FreeCombinationBuf(dest);
197    
198     // �\�������R�s�[����
199     #if ENABLE_CELL_INDEX
200     int idx = dest->idx;
201     #endif
202     *dest = *src;
203     #if ENABLE_CELL_INDEX
204     dest->idx = idx;
205     #endif
206    
207     DupCombinationBuf(dest);
208     }
209    
210 doda 8445 static void BuffSetChar2(buff_char_t *buff, char32_t u32, char property, BOOL half_width, char emoji)
211 maya 3227 {
212 doda 8445 size_t wstr_len;
213     buff_char_t *p = buff;
214 zmatsuo 10354
215     FreeCombinationBuf(p);
216 doda 8445 p->WidthProperty = property;
217 zmatsuo 10308 p->cell = half_width ? 1 : 2;
218 doda 8445 p->u32 = u32;
219     p->u32_last = u32;
220     p->Padding = FALSE;
221     p->Emoji = emoji;
222 zmatsuo 8741 p->fg = AttrDefaultFG;
223     p->bg = AttrDefaultBG;
224 doda 8445
225     //
226     wstr_len = UTF32ToUTF16(u32, &p->wc2[0], 2);
227     switch (wstr_len) {
228     case 0:
229     default:
230     p->wc2[0] = 0;
231     p->wc2[1] = 0;
232     break;
233     case 1:
234     p->wc2[1] = 0;
235     break;
236     case 2:
237     break;
238     }
239 zmatsuo 8745
240     if (u32 < 0x80) {
241     p->ansi_char = (unsigned short)u32;
242     }
243     else {
244 zmatsuo 8770 if (u32 == 0x203e && CodePage == 932) {
245     // U+203e OVERLINE ��������
246     // U+203e��0x7e'~'������
247     //p->ansi_char = 0x7e7e;
248     p->ansi_char = 0x7e;
249     }
250     else {
251     char strA[4];
252     size_t lenA = UTF32ToMBCP(u32, CodePage, strA, sizeof(strA));
253     switch (lenA) {
254 zmatsuo 8745 case 0:
255     default:
256 zmatsuo 10345 p->ansi_char = '?';
257 zmatsuo 8745 break;
258     case 1:
259     p->ansi_char = (unsigned char)strA[0];
260     break;
261     case 2:
262     p->ansi_char = (unsigned char)strA[1] | ((unsigned char)strA[0] << 8);
263     break;
264 zmatsuo 8770 }
265 zmatsuo 8745 }
266     }
267 doda 8445 }
268    
269 zmatsuo 8742 static void BuffSetChar4(buff_char_t *buff, char32_t u32, unsigned char fg, unsigned char bg, unsigned char attr, unsigned char attr2, char property)
270     {
271     buff_char_t *p = buff;
272     BuffSetChar2(p, u32, property, TRUE, FALSE);
273     p->fg = fg;
274     p->bg = bg;
275     p->attr = attr;
276     p->attr2 = attr2;
277     }
278    
279 doda 8445 static void BuffSetChar(buff_char_t *buff, char32_t u32, char property)
280     {
281     BuffSetChar2(buff, u32, property, TRUE, FALSE);
282     }
283    
284     /**
285     * �����������A�R���r�l�[�V����
286     */
287     static void BuffAddChar(buff_char_t *buff, char32_t u32)
288     {
289     buff_char_t *p = buff;
290     assert(p->u32 != 0);
291     // �������������������g������
292     if (p->CombinationCharSize16 < p->CombinationCharCount16 + 2) {
293     size_t new_size = p->CombinationCharSize16;
294     new_size = new_size == 0 ? 5 : new_size * 2;
295 zmatsuo 9404 if (new_size > MAX_CHAR_SIZE) {
296     new_size = MAX_CHAR_SIZE;
297     }
298     if (p->CombinationCharSize16 != new_size) {
299     p->pCombinationChars16 = realloc(p->pCombinationChars16, sizeof(wchar_t) * new_size);
300     p->CombinationCharSize16 = (char)new_size;
301     }
302 doda 8445 }
303     if (p->CombinationCharSize32 < p->CombinationCharCount32 + 2) {
304     size_t new_size = p->CombinationCharSize32;
305     new_size = new_size == 0 ? 5 : new_size * 2;
306 zmatsuo 9404 if (new_size > MAX_CHAR_SIZE) {
307     new_size = MAX_CHAR_SIZE;
308     }
309     if (p->CombinationCharSize32 != new_size) {
310     p->pCombinationChars32 = realloc(p->pCombinationChars32, sizeof(char32_t) * new_size);
311     p->CombinationCharSize32 = (char)new_size;
312     }
313 doda 8445 }
314    
315     // UTF-32
316 zmatsuo 9404 if (p->CombinationCharCount32 < p->CombinationCharSize32) {
317     p->u32_last = u32;
318     p->pCombinationChars32[(size_t)p->CombinationCharCount32] = u32;
319     p->CombinationCharCount32++;
320     }
321 doda 8445
322     // UTF-16
323 zmatsuo 9404 if (p->CombinationCharCount16 < p->CombinationCharSize16) {
324     wchar_t u16_str[2];
325     size_t wlen = UTF32ToUTF16(u32, &u16_str[0], 2);
326     if (p->CombinationCharCount16 + wlen <= p->CombinationCharSize16) {
327     size_t i = (size_t)p->CombinationCharCount16;
328     p->pCombinationChars16[i] = u16_str[0];
329     if (wlen == 2) {
330     i++;
331     p->pCombinationChars16[i] = u16_str[1];
332     }
333 zmatsuo 9839 p->CombinationCharCount16 += (unsigned char)wlen;
334 zmatsuo 9404 }
335 doda 8445 }
336     }
337    
338     static void memcpyW(buff_char_t *dest, const buff_char_t *src, size_t count)
339     {
340     size_t i;
341 zmatsuo 10354
342     if (dest == src || count == 0) {
343     return;
344 doda 8445 }
345 zmatsuo 10354
346     for (i = 0; i < count; i++) {
347     CopyCombinationBuf(dest, src);
348     dest++;
349     src++;
350     }
351 doda 8445 }
352    
353 zmatsuo 8742 static void memsetW(buff_char_t *dest, wchar_t ch, unsigned char fg, unsigned char bg, unsigned char attr, unsigned char attr2, size_t count)
354 doda 8445 {
355     size_t i;
356     for (i=0; i<count; i++) {
357     BuffSetChar(dest, ch, 'H');
358 zmatsuo 8741 dest->fg = fg;
359     dest->bg = bg;
360 zmatsuo 8742 dest->attr = attr;
361     dest->attr2 = attr2;
362 doda 8445 dest++;
363     }
364     }
365    
366     static void memmoveW(buff_char_t *dest, const buff_char_t *src, size_t count)
367     {
368 zmatsuo 10354 size_t i;
369    
370     if (dest == src || count == 0) {
371     return;
372     }
373    
374    
375     if (dest < src) {
376     // �O�����R�s�[����? -> memcpyW() ��ok
377     memcpyW(dest, src, count);
378     }
379     else {
380     // ���������R�s�[����
381     dest += count - 1;
382     src += count - 1;
383     for (i = 0; i < count; i++) {
384     CopyCombinationBuf(dest, src);
385     dest--;
386     src--;
387     }
388     }
389 doda 8445 }
390    
391     static BOOL IsBuffPadding(const buff_char_t *b)
392     {
393     if (b->Padding == TRUE)
394     return TRUE;
395     if (b->u32 == 0)
396     return TRUE;
397     return FALSE;
398     }
399    
400     static BOOL IsBuffFullWidth(const buff_char_t *b)
401     {
402 zmatsuo 10308 if (b->cell != 1)
403 doda 8445 return TRUE;
404     return FALSE;
405     }
406    
407     static LONG GetLinePtr(int Line)
408     {
409 maya 3393 LONG Ptr;
410 maya 3227
411 maya 3393 Ptr = (LONG)(BuffStartAbs + Line) * (LONG)(NumOfColumns);
412     while (Ptr>=BufferSize) {
413     Ptr = Ptr - BufferSize;
414     }
415     return Ptr;
416 maya 3227 }
417    
418 doda 8445 static LONG NextLinePtr(LONG Ptr)
419 maya 3227 {
420 maya 3393 Ptr = Ptr + (LONG)NumOfColumns;
421     if (Ptr >= BufferSize) {
422     Ptr = Ptr - BufferSize;
423     }
424     return Ptr;
425 maya 3227 }
426    
427 doda 8445 static LONG PrevLinePtr(LONG Ptr)
428 maya 3227 {
429 maya 3393 Ptr = Ptr - (LONG)NumOfColumns;
430     if (Ptr < 0) {
431     Ptr = Ptr + BufferSize;
432     }
433     return Ptr;
434 maya 3227 }
435    
436 zmatsuo 8744 /**
437     * �|�C���^�����u���� x,y ��������
438     */
439     static void GetPosFromPtr(const buff_char_t *b, int *bx, int *by)
440     {
441     size_t index = b - CodeBuffW;
442     int x = (int)(index % NumOfColumns);
443     int y = (int)(index / NumOfColumns);
444     if (y >= BuffStartAbs) {
445     y -= BuffStartAbs;
446     }
447     else {
448 zmatsuo 9840 y = y - BuffStartAbs + NumOfLinesInBuff;
449 zmatsuo 8744 }
450     *bx = x;
451     *by = y;
452     }
453    
454 doda 8445 static BOOL ChangeBuffer(int Nx, int Ny)
455 maya 3227 {
456 maya 3393 LONG NewSize;
457     int NxCopy, NyCopy, i;
458     LONG SrcPtr, DestPtr;
459     WORD LockOld;
460 doda 8445 buff_char_t *CodeDestW;
461 maya 3227
462 maya 3393 if (Nx > BuffXMax) {
463     Nx = BuffXMax;
464     }
465     if (ts.ScrollBuffMax > BuffYMax) {
466     ts.ScrollBuffMax = BuffYMax;
467     }
468     if (Ny > ts.ScrollBuffMax) {
469     Ny = ts.ScrollBuffMax;
470     }
471 maya 3227
472 maya 3393 if ( (LONG)Nx * (LONG)Ny > BuffSizeMax ) {
473     Ny = BuffSizeMax / Nx;
474     }
475 maya 3227
476 maya 3393 NewSize = (LONG)Nx * (LONG)Ny;
477 maya 3227
478 doda 8445 CodeDestW = NULL;
479     CodeDestW = malloc(NewSize * sizeof(buff_char_t));
480     if (CodeDestW == NULL) {
481     goto allocate_error;
482     }
483 maya 3227
484 doda 8445 memset(&CodeDestW[0], 0, NewSize * sizeof(buff_char_t));
485 zmatsuo 10354 #if ENABLE_CELL_INDEX
486     {
487     int i;
488     for (i = 0; i < NewSize; i++) {
489     CodeDestW[i].idx = i;
490     }
491     }
492     #endif
493 zmatsuo 8742 memsetW(&CodeDestW[0], 0x20, AttrDefaultFG, AttrDefaultBG, AttrDefault, AttrDefault, NewSize);
494 zmatsuo 8744 if ( CodeBuffW != NULL ) {
495 maya 3393 if ( NumOfColumns > Nx ) {
496     NxCopy = Nx;
497     }
498     else {
499     NxCopy = NumOfColumns;
500     }
501 maya 3227
502 maya 3393 if ( BuffEnd > Ny ) {
503     NyCopy = Ny;
504     }
505     else {
506     NyCopy = BuffEnd;
507     }
508     LockOld = BuffLock;
509     LockBuffer();
510     SrcPtr = GetLinePtr(BuffEnd-NyCopy);
511     DestPtr = 0;
512     for (i = 1 ; i <= NyCopy ; i++) {
513 doda 8445 memcpyW(&CodeDestW[DestPtr],&CodeBuffW[SrcPtr],NxCopy);
514 zmatsuo 8742 if (CodeDestW[DestPtr+NxCopy-1].attr & AttrKanji) {
515 zmatsuo 8744 BuffSetChar(&CodeDestW[DestPtr + NxCopy - 1], ' ', 'H');
516 zmatsuo 8742 CodeDestW[DestPtr+NxCopy-1].attr ^= AttrKanji;
517     }
518 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
519     DestPtr = DestPtr + (LONG)Nx;
520     }
521     FreeBuffer();
522     }
523     else {
524     LockOld = 0;
525     NyCopy = NumOfLines;
526     Selected = FALSE;
527     }
528 maya 3227
529 maya 3393 if (Selected) {
530     SelectStart.y = SelectStart.y - BuffEnd + NyCopy;
531     SelectEnd.y = SelectEnd.y - BuffEnd + NyCopy;
532     if (SelectStart.y < 0) {
533     SelectStart.y = 0;
534     SelectStart.x = 0;
535     }
536     if (SelectEnd.y<0) {
537     SelectEnd.x = 0;
538     SelectEnd.y = 0;
539     }
540 maya 3227
541 maya 3393 Selected = (SelectEnd.y > SelectStart.y) ||
542 zmatsuo 8411 ((SelectEnd.y == SelectStart.y) &&
543 maya 3393 (SelectEnd.x > SelectStart.x));
544     }
545 maya 3227
546 doda 8445 CodeBuffW = CodeDestW;
547 maya 3393 BufferSize = NewSize;
548     NumOfLinesInBuff = Ny;
549     BuffStartAbs = 0;
550     BuffEnd = NyCopy;
551 maya 3227
552 maya 3393 if (BuffEnd==NumOfLinesInBuff) {
553     BuffEndAbs = 0;
554     }
555     else {
556     BuffEndAbs = BuffEnd;
557     }
558 maya 3227
559 maya 3393 PageStart = BuffEnd - NumOfLines;
560    
561     LinePtr = 0;
562     if (LockOld>0) {
563     }
564     else {
565 doda 8445 ;
566 maya 3393 }
567     BuffLock = LockOld;
568    
569     return TRUE;
570 doda 3686
571     allocate_error:
572 doda 8445 if (CodeDestW) free(CodeDestW);
573 doda 3686 return FALSE;
574 maya 3227 }
575    
576 zmatsuo 8748 void InitBuffer(BOOL use_unicode_api)
577 maya 3227 {
578 maya 3393 int Ny;
579 maya 3227
580 zmatsuo 8748 UseUnicodeApi = use_unicode_api;
581    
582 maya 3393 /* setup terminal */
583     NumOfColumns = ts.TerminalWidth;
584     NumOfLines = ts.TerminalHeight;
585 maya 3227
586 doda 6785 if (NumOfColumns <= 0)
587     NumOfColumns = 80;
588     else if (NumOfColumns > TermWidthMax)
589     NumOfColumns = TermWidthMax;
590    
591     if (NumOfLines <= 0)
592     NumOfLines = 24;
593     else if (NumOfLines > TermHeightMax)
594     NumOfLines = TermHeightMax;
595    
596 maya 3393 /* setup window */
597     if (ts.EnableScrollBuff>0) {
598     if (ts.ScrollBuffSize < NumOfLines) {
599     ts.ScrollBuffSize = NumOfLines;
600     }
601     Ny = ts.ScrollBuffSize;
602     }
603     else {
604     Ny = NumOfLines;
605     }
606 maya 3227
607 maya 3393 if (! ChangeBuffer(NumOfColumns,Ny)) {
608     PostQuitMessage(0);
609     }
610 maya 3227
611 maya 3393 if (ts.EnableScrollBuff>0) {
612     ts.ScrollBuffSize = NumOfLinesInBuff;
613     }
614 maya 3227
615 maya 3393 StatusLine = 0;
616 maya 3227 }
617    
618 doda 8445 static void NewLine(int Line)
619 maya 3227 {
620 maya 3393 LinePtr = GetLinePtr(Line);
621 maya 3227 }
622    
623 zmatsuo 10100 void LockBuffer(void)
624 maya 3227 {
625 maya 3393 BuffLock++;
626     if (BuffLock>1) {
627     return;
628     }
629     NewLine(PageStart+CursorY);
630 maya 3227 }
631    
632 zmatsuo 10100 void UnlockBuffer(void)
633 maya 3227 {
634 maya 3393 if (BuffLock==0) {
635     return;
636     }
637     BuffLock--;
638     if (BuffLock>0) {
639     return;
640     }
641 maya 3227 }
642    
643 zmatsuo 10354 void FreeBuffer(void)
644 zmatsuo 10104 {
645     int i;
646 zmatsuo 10354
647 zmatsuo 10104 for (i = 0; i < NumOfColumns * NumOfLinesInBuff; i++) {
648 zmatsuo 10354 FreeCombinationBuf(&CodeBuffW[i]);
649 zmatsuo 10104 }
650    
651 maya 3393 BuffLock = 1;
652     UnlockBuffer();
653 doda 8445 if (CodeBuffW != NULL) {
654     free(CodeBuffW);
655     CodeBuffW = NULL;
656 maya 3393 }
657 maya 3227 }
658    
659 zmatsuo 10100 void BuffAllSelect(void)
660 maya 3227 {
661     SelectStart.x = 0;
662     SelectStart.y = 0;
663     SelectEnd.x = 0;
664     SelectEnd.y = BuffEnd;
665     // SelectEnd.x = NumOfColumns;
666     // SelectEnd.y = BuffEnd - 1;
667 doda 8400 Selecting = TRUE;
668 maya 3227 }
669    
670 zmatsuo 10100 void BuffScreenSelect(void)
671 maya 3227 {
672     int X, Y;
673     DispConvWinToScreen(0, 0, &X, &Y, NULL);
674     SelectStart.x = X;
675     SelectStart.y = Y + PageStart;
676     SelectEnd.x = 0;
677     SelectEnd.y = SelectStart.y + NumOfLines;
678     // SelectEnd.x = X + NumOfColumns;
679     // SelectEnd.y = Y + PageStart + NumOfLines - 1;
680 doda 8400 Selecting = TRUE;
681 maya 3227 }
682    
683 zmatsuo 10100 void BuffCancelSelection(void)
684 maya 3227 {
685     SelectStart.x = 0;
686     SelectStart.y = 0;
687     SelectEnd.x = 0;
688     SelectEnd.y = 0;
689 doda 8400 Selecting = FALSE;
690 maya 3227 }
691    
692 zmatsuo 10100 void BuffReset(void)
693 maya 3227 // Reset buffer status. don't update real display
694     // called by ResetTerminal()
695     {
696 maya 3393 int i;
697 maya 3227
698 maya 3393 /* Cursor */
699     NewLine(PageStart);
700     WinOrgX = 0;
701     WinOrgY = 0;
702     NewOrgX = 0;
703     NewOrgY = 0;
704 maya 3227
705 maya 3393 /* Top/bottom margin */
706     CursorTop = 0;
707     CursorBottom = NumOfLines-1;
708 doda 5324 CursorLeftM = 0;
709     CursorRightM = NumOfColumns-1;
710 maya 3227
711 maya 3393 /* Tab stops */
712     NTabStops = (NumOfColumns-1) >> 3;
713     for (i=1 ; i<=NTabStops ; i++) {
714 doda 8445 TabStops[i-1] = (WORD)(i*8);
715 maya 3393 }
716 maya 3227
717 maya 3393 /* Initialize text selection region */
718     SelectStart.x = 0;
719     SelectStart.y = 0;
720     SelectEnd = SelectStart;
721     SelectEndOld = SelectStart;
722     Selected = FALSE;
723 maya 3227
724 maya 3393 StrChangeCount = 0;
725     Wrap = FALSE;
726     StatusLine = 0;
727 maya 3227
728 maya 3393 SeveralPageSelect = FALSE; // yutaka
729 doda 3745
730     /* Alternate Screen Buffer */
731     BuffDiscardSavedScreen();
732 maya 3227 }
733    
734 zmatsuo 9839 static void BuffScroll(int Count, int Bottom)
735 maya 3227 {
736 maya 3393 int i, n;
737     LONG SrcPtr, DestPtr;
738     int BuffEndOld;
739 maya 3227
740 maya 3393 if (Count>NumOfLinesInBuff) {
741     Count = NumOfLinesInBuff;
742     }
743 maya 3227
744 maya 3393 DestPtr = GetLinePtr(PageStart+NumOfLines-1+Count);
745     n = Count;
746     if (Bottom<NumOfLines-1) {
747     SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
748     for (i=NumOfLines-1; i>=Bottom+1; i--) {
749 doda 8445 memcpyW(&(CodeBuffW[DestPtr]),&(CodeBuffW[SrcPtr]),NumOfColumns);
750 zmatsuo 8742 memsetW(&(CodeBuffW[SrcPtr]),0x20,CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
751 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
752     DestPtr = PrevLinePtr(DestPtr);
753     n--;
754     }
755     }
756     for (i = 1 ; i <= n ; i++) {
757 zmatsuo 8741 buff_char_t *b = &CodeBuffW[DestPtr];
758 zmatsuo 8742 memsetW(b ,0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
759 maya 3393 DestPtr = PrevLinePtr(DestPtr);
760     }
761 maya 3227
762 maya 3393 BuffEndAbs = BuffEndAbs + Count;
763     if (BuffEndAbs >= NumOfLinesInBuff) {
764     BuffEndAbs = BuffEndAbs - NumOfLinesInBuff;
765     }
766     BuffEndOld = BuffEnd;
767     BuffEnd = BuffEnd + Count;
768     if (BuffEnd >= NumOfLinesInBuff) {
769     BuffEnd = NumOfLinesInBuff;
770     BuffStartAbs = BuffEndAbs;
771     }
772     PageStart = BuffEnd-NumOfLines;
773 maya 3227
774 maya 3393 if (Selected) {
775     SelectStart.y = SelectStart.y - Count + BuffEnd - BuffEndOld;
776     SelectEnd.y = SelectEnd.y - Count + BuffEnd - BuffEndOld;
777     if ( SelectStart.y<0 ) {
778     SelectStart.x = 0;
779     SelectStart.y = 0;
780     }
781     if ( SelectEnd.y<0 ) {
782     SelectEnd.x = 0;
783     SelectEnd.y = 0;
784     }
785     Selected = (SelectEnd.y > SelectStart.y) ||
786     ((SelectEnd.y==SelectStart.y) &&
787     (SelectEnd.x > SelectStart.x));
788     }
789 maya 3227
790 maya 3393 NewLine(PageStart+CursorY);
791 maya 3227 }
792    
793     // If cursor is on left/right half of a Kanji, erase it.
794     // LR: left(0)/right(1) flag
795 doda 8445 // LR 0 �J�[�\��������������
796     // 1 �J�[�\�����������E��
797     static void EraseKanji(int LR)
798     {
799 zmatsuo 8739 buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
800    
801 doda 8445 buff_char_t *p;
802     int bx;
803     if (CursorX < LR) {
804     // �S�p������������
805     return;
806     }
807     bx = CursorX-LR;
808     p = &CodeLineW[bx];
809     if (IsBuffFullWidth(p)) {
810     // �S�p��������
811     BuffSetChar(p, ' ', 'H');
812 zmatsuo 8742 p->attr = CurCharAttr.Attr;
813     p->attr2 = CurCharAttr.Attr2;
814 zmatsuo 8741 p->fg = CurCharAttr.Fore;
815     p->bg = CurCharAttr.Back;
816 doda 8445 if (bx+1 < NumOfColumns) {
817     BuffSetChar(p + 1, ' ', 'H');
818 zmatsuo 8742 (p+1)->attr = CurCharAttr.Attr;
819     (p+1)->attr2 = CurCharAttr.Attr2;
820 zmatsuo 8741 (p+1)->fg = CurCharAttr.Fore;
821     (p+1)->bg = CurCharAttr.Back;
822 doda 8445 }
823     }
824 maya 3227 }
825    
826 zmatsuo 8785 static void EraseKanjiOnLRMargin(LONG ptr, int count)
827 doda 5371 {
828     int i;
829     LONG pos;
830    
831     if (count < 1)
832     return;
833    
834     for (i=0; i<count; i++) {
835     pos = ptr + CursorLeftM-1;
836 zmatsuo 8742 if (CursorLeftM>0 && (CodeBuffW[pos].attr & AttrKanji)) {
837 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
838 zmatsuo 8742 CodeBuffW[pos].attr &= ~AttrKanji;
839 doda 5371 pos++;
840 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
841 zmatsuo 8742 CodeBuffW[pos].attr &= ~AttrKanji;
842 doda 5371 }
843     pos = ptr + CursorRightM;
844 zmatsuo 8742 if (CursorRightM < NumOfColumns-1 && (CodeBuffW[pos].attr & AttrKanji)) {
845 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
846 zmatsuo 8742 CodeBuffW[pos].attr &= ~AttrKanji;
847 doda 5371 pos++;
848 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
849 zmatsuo 8742 CodeBuffW[pos].attr &= ~AttrKanji;
850 doda 5371 }
851     ptr = NextLinePtr(ptr);
852     }
853     }
854    
855 doda 8445 // Insert space characters at the current position
856     // Count: Number of characters to be inserted
857 maya 3227 void BuffInsertSpace(int Count)
858 doda 8445 {
859 zmatsuo 8739 buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
860 doda 8445 int MoveLen;
861     int extr = 0;
862     int sx;
863     buff_char_t *b;
864    
865     if (CursorX < CursorLeftM || CursorX > CursorRightM)
866     return;
867    
868     NewLine(PageStart + CursorY);
869    
870     sx = CursorX;
871     b = &CodeLineW[CursorX];
872     if (IsBuffPadding(b)) {
873     /* if cursor is on right half of a kanji, erase the kanji */
874     BuffSetChar(b - 1, ' ', 'H');
875     BuffSetChar(b, ' ', 'H');
876 zmatsuo 8742 b->attr &= ~AttrKanji;
877 doda 8445 sx--;
878     extr++;
879     }
880    
881 zmatsuo 8742 if (CursorRightM < NumOfColumns - 1 && (CodeLineW[CursorRightM].attr & AttrKanji)) {
882 doda 8445 BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
883 zmatsuo 8742 CodeLineW[CursorRightM + 1].attr &= ~AttrKanji;
884 doda 8445 extr++;
885     }
886    
887     if (Count > CursorRightM + 1 - CursorX)
888     Count = CursorRightM + 1 - CursorX;
889    
890     MoveLen = CursorRightM + 1 - CursorX - Count;
891    
892     if (MoveLen > 0) {
893     memmoveW(&(CodeLineW[CursorX + Count]), &(CodeLineW[CursorX]), MoveLen);
894     }
895 zmatsuo 8742 memsetW(&(CodeLineW[CursorX]), 0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2, Count);
896 doda 8445 /* last char in current line is kanji first? */
897 zmatsuo 8742 if ((CodeLineW[CursorRightM].attr & AttrKanji) != 0) {
898 doda 8445 /* then delete it */
899     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
900 zmatsuo 8742 CodeLineW[CursorRightM].attr &= ~AttrKanji;
901 doda 8445 }
902     BuffUpdateRect(sx, CursorY, CursorRightM + extr, CursorY);
903     }
904 doda 5324
905 zmatsuo 10639 /**
906     * Erase characters from cursor to the end of screen
907     */
908 zmatsuo 10100 void BuffEraseCurToEnd(void)
909 maya 3227 {
910 maya 3393 LONG TmpPtr;
911     int offset;
912     int i, YEnd;
913 maya 3227
914 maya 3393 NewLine(PageStart+CursorY);
915 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
916 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
917     }
918     offset = CursorX;
919     TmpPtr = GetLinePtr(PageStart+CursorY);
920     YEnd = NumOfLines-1;
921 doda 5324 if (StatusLine && !isCursorOnStatusLine) {
922 maya 3393 YEnd--;
923     }
924     for (i = CursorY ; i <= YEnd ; i++) {
925 zmatsuo 8742 memsetW(&(CodeBuffW[TmpPtr+offset]),0x20,CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
926 maya 3393 offset = 0;
927     TmpPtr = NextLinePtr(TmpPtr);
928     }
929 zmatsuo 10639
930 maya 3393 /* update window */
931 zmatsuo 10639 BuffDrawLineI(-1, -1, CursorY + PageStart, CursorX, NumOfColumns);
932     for (i = CursorY + 1; i <= YEnd; i++) {
933     BuffDrawLineI(-1, -1, i + PageStart, 0, NumOfColumns);
934     }
935 maya 3227 }
936    
937 zmatsuo 10639 /**
938     * Erase characters from home to cursor
939     */
940 zmatsuo 10100 void BuffEraseHomeToCur(void)
941 maya 3227 {
942 maya 3393 LONG TmpPtr;
943     int offset;
944     int i, YHome;
945 maya 3227
946 maya 3393 NewLine(PageStart+CursorY);
947 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
948 maya 3393 EraseKanji(0); /* if cursor is on left half of a kanji, erase the kanji */
949     }
950     offset = NumOfColumns;
951 doda 5324 if (isCursorOnStatusLine) {
952 maya 3393 YHome = CursorY;
953     }
954     else {
955     YHome = 0;
956     }
957     TmpPtr = GetLinePtr(PageStart+YHome);
958     for (i = YHome ; i <= CursorY ; i++) {
959     if (i==CursorY) {
960     offset = CursorX+1;
961     }
962 zmatsuo 8742 memsetW(&(CodeBuffW[TmpPtr]),0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, offset);
963 maya 3393 TmpPtr = NextLinePtr(TmpPtr);
964     }
965 maya 3227
966 maya 3393 /* update window */
967 zmatsuo 10639 for (i = YHome; i < CursorY; i++) {
968     BuffDrawLineI(-1, -1, i + PageStart, 0, NumOfColumns);
969     }
970     BuffDrawLineI(-1, -1, CursorY + PageStart, 0, CursorX-1);
971 maya 3227 }
972    
973     void BuffInsertLines(int Count, int YEnd)
974     // Insert lines at current position
975     // Count: number of lines to be inserted
976     // YEnd: bottom line number of scroll region (screen coordinate)
977     {
978 doda 5324 int i, linelen;
979 doda 5371 int extl=0, extr=0;
980 maya 3393 LONG SrcPtr, DestPtr;
981 maya 3227
982 maya 3393 BuffUpdateScroll();
983 maya 3227
984 doda 5371 if (CursorLeftM > 0)
985     extl = 1;
986     if (CursorRightM < NumOfColumns-1)
987     extr = 1;
988     if (extl || extr)
989     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
990    
991 doda 5324 SrcPtr = GetLinePtr(PageStart+YEnd-Count) + CursorLeftM;
992     DestPtr = GetLinePtr(PageStart+YEnd) + CursorLeftM;
993     linelen = CursorRightM - CursorLeftM + 1;
994 maya 3393 for (i= YEnd-Count ; i>=CursorY ; i--) {
995 doda 8445 memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
996 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
997     DestPtr = PrevLinePtr(DestPtr);
998     }
999     for (i = 1 ; i <= Count ; i++) {
1000 zmatsuo 8742 memsetW(&(CodeBuffW[DestPtr]), 0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, linelen);
1001 maya 3393 DestPtr = PrevLinePtr(DestPtr);
1002     }
1003 maya 3227
1004 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || !DispInsertLines(Count, YEnd)) {
1005 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
1006 maya 3393 }
1007 maya 3227 }
1008    
1009 zmatsuo 10639 /**
1010     * erase characters in the current line
1011     * @param start position of erasing
1012     * @param Count: number of characters to be erased
1013     */
1014 maya 3227 void BuffEraseCharsInLine(int XStart, int Count)
1015     {
1016 zmatsuo 8739 buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1017 maya 3393 BOOL LineContinued=FALSE;
1018 doda 3312
1019 zmatsuo 8742 if (ts.EnableContinuedLineCopy && XStart == 0 && (CodeLineW[0].attr & AttrLineContinued)) {
1020 maya 3393 LineContinued = TRUE;
1021     }
1022 doda 3312
1023 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1024 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1025     }
1026 maya 3227
1027 maya 3393 NewLine(PageStart+CursorY);
1028 zmatsuo 8742 memsetW(&(CodeLineW[XStart]),0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, Count);
1029 maya 3227
1030 maya 3393 if (ts.EnableContinuedLineCopy) {
1031     if (LineContinued) {
1032     BuffLineContinued(TRUE);
1033     }
1034    
1035     if (XStart + Count >= NumOfColumns) {
1036 zmatsuo 8742 CodeBuffW[NextLinePtr(LinePtr)].attr &= ~AttrLineContinued;
1037 maya 3393 }
1038     }
1039 doda 3312
1040 zmatsuo 10639 BuffDrawLineI(-1, -1, CursorY + PageStart, XStart, XStart + Count);
1041 maya 3227 }
1042    
1043     void BuffDeleteLines(int Count, int YEnd)
1044     // Delete lines from current line
1045     // Count: number of lines to be deleted
1046     // YEnd: bottom line number of scroll region (screen coordinate)
1047     {
1048 doda 5324 int i, linelen;
1049 doda 5371 int extl=0, extr=0;
1050 maya 3393 LONG SrcPtr, DestPtr;
1051 maya 3227
1052 maya 3393 BuffUpdateScroll();
1053 maya 3227
1054 doda 5371 if (CursorLeftM > 0)
1055     extl = 1;
1056     if (CursorRightM < NumOfColumns-1)
1057     extr = 1;
1058     if (extl || extr)
1059     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
1060    
1061 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorY+Count) + (LONG)CursorLeftM;
1062     DestPtr = GetLinePtr(PageStart+CursorY) + (LONG)CursorLeftM;
1063     linelen = CursorRightM - CursorLeftM + 1;
1064 maya 3393 for (i=CursorY ; i<= YEnd-Count ; i++) {
1065 doda 8445 memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
1066 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
1067     DestPtr = NextLinePtr(DestPtr);
1068     }
1069     for (i = YEnd+1-Count ; i<=YEnd ; i++) {
1070 zmatsuo 8742 memsetW(&(CodeBuffW[DestPtr]), 0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, linelen);
1071 maya 3393 DestPtr = NextLinePtr(DestPtr);
1072     }
1073 maya 3227
1074 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || ! DispDeleteLines(Count,YEnd)) {
1075 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
1076 maya 3393 }
1077 maya 3227 }
1078    
1079     // Delete characters in current line from cursor
1080     // Count: number of characters to be deleted
1081 doda 8445 void BuffDeleteChars(int Count)
1082 maya 3227 {
1083 zmatsuo 8739 buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1084 doda 5325 int MoveLen;
1085 doda 8445 int extr = 0;
1086     buff_char_t *b;
1087    
1088     if (Count > CursorRightM + 1 - CursorX)
1089     Count = CursorRightM + 1 - CursorX;
1090    
1091     if (CursorX < CursorLeftM || CursorX > CursorRightM)
1092     return;
1093    
1094     NewLine(PageStart + CursorY);
1095    
1096     b = &CodeLineW[CursorX];
1097    
1098     if (IsBuffPadding(b)) {
1099     // �S�p���E���A�S�p���X�y�[�X���u��������
1100     BuffSetChar(b - 1, ' ', 'H');
1101     BuffSetChar(b, ' ', 'H');
1102     }
1103     if (IsBuffFullWidth(b)) {
1104     // �S�p�������A�S�p���X�y�[�X���u��������
1105     BuffSetChar(b, ' ', 'H');
1106     BuffSetChar(b + 1, ' ', 'H');
1107     }
1108     if (Count > 1) {
1109     // �I�[���`�F�b�N
1110     if (IsBuffPadding(b + Count)) {
1111     // �S�p���E���A�S�p���X�y�[�X���u��������
1112     BuffSetChar(b + Count - 1, ' ', 'H');
1113     BuffSetChar(b + Count, ' ', 'H');
1114     }
1115     }
1116    
1117 zmatsuo 8742 if (CursorRightM < NumOfColumns - 1 && (CodeLineW[CursorRightM].attr & AttrKanji)) {
1118 doda 8445 BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
1119 zmatsuo 8742 CodeLineW[CursorRightM].attr &= ~AttrKanji;
1120 doda 8445 BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
1121 zmatsuo 8742 CodeLineW[CursorRightM + 1].attr &= ~AttrKanji;
1122 doda 8445 extr = 1;
1123     }
1124    
1125     MoveLen = CursorRightM + 1 - CursorX - Count;
1126    
1127     if (MoveLen > 0) {
1128     memmoveW(&(CodeLineW[CursorX]), &(CodeLineW[CursorX + Count]), MoveLen);
1129     }
1130 zmatsuo 8742 memsetW(&(CodeLineW[CursorX + MoveLen]), ' ', CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, Count);
1131 doda 8445
1132     BuffUpdateRect(CursorX, CursorY, CursorRightM + extr, CursorY);
1133     }
1134 doda 5325
1135 zmatsuo 10639 /**
1136     * Erase characters in current line from cursor
1137     * @param Count number of characters to be deleted
1138     */
1139 doda 8445 void BuffEraseChars(int Count)
1140 maya 3227 {
1141 zmatsuo 8739 buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1142 doda 8445 int extr = 0;
1143     int sx = CursorX;
1144     buff_char_t *b;
1145     NewLine(PageStart + CursorY);
1146    
1147     if (Count > NumOfColumns - CursorX) {
1148     Count = NumOfColumns - CursorX;
1149     }
1150    
1151     b = &CodeLineW[CursorX];
1152     if (IsBuffPadding(b)) {
1153     // �S�p���E���A�S�p���X�y�[�X���u��������
1154     BuffSetChar(b - 1, ' ', 'H');
1155     BuffSetChar(b, ' ', 'H');
1156     sx--;
1157     extr++;
1158     }
1159     if (IsBuffFullWidth(b)) {
1160     // �S�p�������A�S�p���X�y�[�X���u��������
1161     BuffSetChar(b, ' ', 'H');
1162     BuffSetChar(b + 1, ' ', 'H');
1163     if (Count == 1) {
1164     extr++;
1165     }
1166     }
1167     if (Count > 1) {
1168     // �I�[���`�F�b�N
1169     if (IsBuffPadding(b + Count)) {
1170     // �S�p���E���A�S�p���X�y�[�X���u��������
1171     BuffSetChar(b + Count - 1, ' ', 'H');
1172     BuffSetChar(b + Count, ' ', 'H');
1173     extr++;
1174     }
1175     }
1176    
1177 zmatsuo 8742 memsetW(&(CodeLineW[CursorX]), 0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, Count);
1178 doda 8445
1179     /* update window */
1180 zmatsuo 10639 BuffDrawLineI(-1, -1, CursorY + PageStart, sx, sx + Count + extr);
1181 doda 8445 }
1182 maya 3227
1183 zmatsuo 10100 void BuffFillWithE(void)
1184 maya 3227 // Fill screen with 'E' characters
1185     {
1186 maya 3393 LONG TmpPtr;
1187     int i;
1188 maya 3227
1189 maya 3393 TmpPtr = GetLinePtr(PageStart);
1190     for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
1191 zmatsuo 8742 memsetW(&(CodeBuffW[TmpPtr]),'E', AttrDefaultFG, AttrDefaultBG, AttrDefault, AttrDefault, NumOfColumns);
1192 maya 3393 TmpPtr = NextLinePtr(TmpPtr);
1193     }
1194     BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
1195 maya 3227 }
1196    
1197     void BuffDrawLine(TCharAttr Attr, int Direction, int C)
1198     { // IO-8256 terminal
1199 maya 3393 LONG Ptr;
1200     int i, X, Y;
1201 maya 3227
1202 maya 3393 if (C==0) {
1203     return;
1204     }
1205     Attr.Attr |= AttrSpecial;
1206 maya 3227
1207 maya 3393 switch (Direction) {
1208     case 3:
1209     case 4:
1210     if (Direction==3) {
1211     if (CursorY==0) {
1212     return;
1213     }
1214     Y = CursorY-1;
1215     }
1216     else {
1217     if (CursorY==NumOfLines-1-StatusLine) {
1218     return;
1219     }
1220     Y = CursorY+1;
1221     }
1222     if (CursorX+C > NumOfColumns) {
1223     C = NumOfColumns-CursorX;
1224     }
1225     Ptr = GetLinePtr(PageStart+Y);
1226 zmatsuo 8742 memsetW(&(CodeBuffW[Ptr+CursorX]),'q', Attr.Fore, Attr.Back, Attr.Attr, Attr.Attr2, C);
1227 maya 3393 BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
1228     break;
1229     case 5:
1230     case 6:
1231     if (Direction==5) {
1232     if (CursorX==0) {
1233     return;
1234     }
1235     X = CursorX - 1;
1236     }
1237     else {
1238     if (CursorX==NumOfColumns-1) {
1239     X = CursorX-1;
1240     }
1241     else {
1242     X = CursorX+1;
1243     }
1244     }
1245     Ptr = GetLinePtr(PageStart+CursorY);
1246     if (CursorY+C > NumOfLines-StatusLine) {
1247     C = NumOfLines-StatusLine-CursorY;
1248     }
1249     for (i=1; i<=C; i++) {
1250 zmatsuo 8744 BuffSetChar4(&CodeBuffW[Ptr+X], 'x', Attr.Fore, Attr.Back, Attr.Attr, Attr.Attr2, 'H');
1251 maya 3393 Ptr = NextLinePtr(Ptr);
1252     }
1253     BuffUpdateRect(X,CursorY,X,CursorY+C-1);
1254     break;
1255     }
1256 maya 3227 }
1257    
1258 zmatsuo 8742 void BuffEraseBox(int XStart, int YStart, int XEnd, int YEnd)
1259 maya 3227 {
1260 maya 3393 int C, i;
1261     LONG Ptr;
1262 maya 3227
1263 maya 3393 if (XEnd>NumOfColumns-1) {
1264     XEnd = NumOfColumns-1;
1265     }
1266     if (YEnd>NumOfLines-1-StatusLine) {
1267     YEnd = NumOfLines-1-StatusLine;
1268     }
1269     if (XStart>XEnd) {
1270     return;
1271     }
1272     if (YStart>YEnd) {
1273     return;
1274     }
1275     C = XEnd-XStart+1;
1276     Ptr = GetLinePtr(PageStart+YStart);
1277     for (i=YStart; i<=YEnd; i++) {
1278     if ((XStart>0) &&
1279 zmatsuo 8742 ((CodeBuffW[Ptr+XStart-1].attr & AttrKanji) != 0)) {
1280     BuffSetChar4(&CodeBuffW[Ptr+XStart-1], 0x20, CurCharAttr.Fore, CurCharAttr.Back, CurCharAttr.Attr, CurCharAttr.Attr2, 'H');
1281 maya 3393 }
1282     if ((XStart+C<NumOfColumns) &&
1283 zmatsuo 8742 ((CodeBuffW[Ptr+XStart+C-1].attr & AttrKanji) != 0)) {
1284     BuffSetChar4(&CodeBuffW[Ptr+XStart+C], 0x20, CurCharAttr.Fore, CurCharAttr.Back, CurCharAttr.Attr, CurCharAttr.Attr2, 'H');
1285 maya 3393 }
1286 zmatsuo 8742 memsetW(&(CodeBuffW[Ptr+XStart]),0x20, CurCharAttr.Fore, CurCharAttr.Back, AttrDefault, CurCharAttr.Attr2 & Attr2ColorMask, C);
1287 maya 3393 Ptr = NextLinePtr(Ptr);
1288     }
1289     BuffUpdateRect(XStart,YStart,XEnd,YEnd);
1290 maya 3227 }
1291    
1292 doda 5090 void BuffFillBox(char ch, int XStart, int YStart, int XEnd, int YEnd)
1293     {
1294     int Cols, i;
1295     LONG Ptr;
1296    
1297     if (XEnd>NumOfColumns-1) {
1298     XEnd = NumOfColumns-1;
1299     }
1300     if (YEnd>NumOfLines-1-StatusLine) {
1301     YEnd = NumOfLines-1-StatusLine;
1302     }
1303     if (XStart>XEnd) {
1304     return;
1305     }
1306     if (YStart>YEnd) {
1307     return;
1308     }
1309     Cols = XEnd-XStart+1;
1310     Ptr = GetLinePtr(PageStart+YStart);
1311     for (i=YStart; i<=YEnd; i++) {
1312     if ((XStart>0) &&
1313 zmatsuo 8742 ((CodeBuffW[Ptr+XStart-1].attr & AttrKanji) != 0)) {
1314 doda 8446 BuffSetChar(&CodeBuffW[Ptr + XStart - 1], 0x20, 'H');
1315 zmatsuo 8742 CodeBuffW[Ptr+XStart-1].attr ^= AttrKanji;
1316 doda 5090 }
1317     if ((XStart+Cols<NumOfColumns) &&
1318 zmatsuo 8742 ((CodeBuffW[Ptr+XStart+Cols-1].attr & AttrKanji) != 0)) {
1319 doda 8446 BuffSetChar(&CodeBuffW[Ptr + XStart + Cols], 0x20, 'H');
1320 doda 5090 }
1321 zmatsuo 8742 memsetW(&(CodeBuffW[Ptr+XStart]), ch, CurCharAttr.Fore, CurCharAttr.Back, CurCharAttr.Attr, CurCharAttr.Attr2, Cols);
1322 doda 5090 Ptr = NextLinePtr(Ptr);
1323     }
1324     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1325     }
1326    
1327 doda 6174 //
1328     // TODO: 1 origin �������������� 0 origin ������
1329     //
1330 doda 5089 void BuffCopyBox(
1331     int SrcXStart, int SrcYStart, int SrcXEnd, int SrcYEnd, int SrcPage,
1332     int DstX, int DstY, int DstPage)
1333     {
1334     int i, C, L;
1335     LONG SPtr, DPtr;
1336    
1337     SrcXStart--;
1338     SrcYStart--;
1339     SrcXEnd--;
1340     SrcYEnd--;
1341     SrcPage--;
1342     DstX--;
1343     DstY--;
1344     DstPage--;
1345    
1346     if (SrcXEnd > NumOfColumns - 1) {
1347     SrcXEnd = NumOfColumns-1;
1348     }
1349     if (SrcYEnd > NumOfLines-1-StatusLine) {
1350     SrcYEnd = NumOfColumns-1;
1351     }
1352     if (SrcXStart > SrcXEnd ||
1353     SrcYStart > SrcYEnd ||
1354     DstX > NumOfColumns-1 ||
1355     DstY > NumOfLines-1-StatusLine) {
1356     return;
1357     }
1358    
1359     C = SrcXEnd - SrcXStart + 1;
1360     if (DstX + C > NumOfColumns) {
1361     C = NumOfColumns - DstX;
1362     }
1363     L = SrcYEnd - SrcYStart + 1;
1364     if (DstY + C > NumOfColumns) {
1365     C = NumOfColumns - DstX;
1366     }
1367    
1368     if (SrcXStart > DstX) {
1369     SPtr = GetLinePtr(PageStart+SrcYStart);
1370     DPtr = GetLinePtr(PageStart+DstY);
1371     for (i=0; i<L; i++) {
1372 doda 8445 memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1373 doda 5089 SPtr = NextLinePtr(SPtr);
1374     DPtr = NextLinePtr(DPtr);
1375     }
1376     }
1377     else if (SrcXStart < DstX) {
1378     SPtr = GetLinePtr(PageStart+SrcYEnd);
1379     DPtr = GetLinePtr(PageStart+DstY+L-1);
1380     for (i=L; i>0; i--) {
1381 doda 8445 memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1382 doda 5089 SPtr = PrevLinePtr(SPtr);
1383     DPtr = PrevLinePtr(DPtr);
1384     }
1385     }
1386     else if (SrcYStart != DstY) {
1387     SPtr = GetLinePtr(PageStart+SrcYStart);
1388     DPtr = GetLinePtr(PageStart+DstY);
1389     for (i=0; i<L; i++) {
1390 doda 8445 memmoveW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1391 doda 5089 SPtr = NextLinePtr(SPtr);
1392     DPtr = NextLinePtr(DPtr);
1393     }
1394     }
1395     BuffUpdateRect(DstX,DstY,DstX+C-1,DstY+L-1);
1396     }
1397    
1398 doda 5095 void BuffChangeAttrBox(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1399     {
1400     int C, i, j;
1401     LONG Ptr;
1402    
1403     if (XEnd>NumOfColumns-1) {
1404     XEnd = NumOfColumns-1;
1405     }
1406     if (YEnd>NumOfLines-1-StatusLine) {
1407     YEnd = NumOfLines-1-StatusLine;
1408     }
1409     if (XStart>XEnd || YStart>YEnd) {
1410     return;
1411     }
1412     C = XEnd-XStart+1;
1413     Ptr = GetLinePtr(PageStart+YStart);
1414    
1415     if (mask) { // DECCARA
1416     for (i=YStart; i<=YEnd; i++) {
1417     j = Ptr+XStart-1;
1418 zmatsuo 8742 if (XStart>0 && (CodeBuffW[j].attr & AttrKanji)) {
1419     CodeBuffW[j].attr = (CodeBuffW[j].attr & ~mask->Attr) | attr->Attr;
1420     CodeBuffW[j].attr2 = (CodeBuffW[j].attr2 & ~mask->Attr2) | attr->Attr2;
1421 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[j].fg = attr->Fore; }
1422     if (mask->Attr2 & Attr2Back) { CodeBuffW[j].bg = attr->Back; }
1423 doda 5095 }
1424 doda 7083 while (++j < Ptr+XStart+C) {
1425 zmatsuo 8742 CodeBuffW[j].attr = (CodeBuffW[j].attr & ~mask->Attr) | attr->Attr;
1426     CodeBuffW[j].attr2 = (CodeBuffW[j].attr2 & ~mask->Attr2) | attr->Attr2;
1427 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[j].fg = attr->Fore; }
1428     if (mask->Attr2 & Attr2Back) { CodeBuffW[j].bg = attr->Back; }
1429 doda 5095 }
1430 zmatsuo 8742 if (XStart+C<NumOfColumns && (CodeBuffW[j-1].attr & AttrKanji)) {
1431     CodeBuffW[j].attr = (CodeBuffW[j].attr & ~mask->Attr) | attr->Attr;
1432     CodeBuffW[j].attr2 = (CodeBuffW[j].attr2 & ~mask->Attr2) | attr->Attr2;
1433 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[j].fg = attr->Fore; }
1434     if (mask->Attr2 & Attr2Back) { CodeBuffW[j].bg = attr->Back; }
1435 doda 5095 }
1436     Ptr = NextLinePtr(Ptr);
1437     }
1438     }
1439     else { // DECRARA
1440     for (i=YStart; i<=YEnd; i++) {
1441     j = Ptr+XStart-1;
1442 zmatsuo 8742 if (XStart>0 && (CodeBuffW[j].attr & AttrKanji)) {
1443     CodeBuffW[j].attr ^= attr->Attr;
1444 doda 5095 }
1445 doda 7083 while (++j < Ptr+XStart+C) {
1446 zmatsuo 8742 CodeBuffW[j].attr ^= attr->Attr;
1447 doda 5095 }
1448 zmatsuo 8742 if (XStart+C<NumOfColumns && (CodeBuffW[j-1].attr & AttrKanji)) {
1449     CodeBuffW[j].attr ^= attr->Attr;
1450 doda 5095 }
1451     Ptr = NextLinePtr(Ptr);
1452     }
1453     }
1454     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1455     }
1456    
1457 doda 7086 void BuffChangeAttrStream(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1458     {
1459     int i, j, endp;
1460     LONG Ptr;
1461    
1462     if (XEnd>NumOfColumns-1) {
1463     XEnd = NumOfColumns-1;
1464     }
1465     if (YEnd>NumOfLines-1-StatusLine) {
1466     YEnd = NumOfLines-1-StatusLine;
1467     }
1468     if (XStart>XEnd || YStart>YEnd) {
1469     return;
1470     }
1471    
1472     Ptr = GetLinePtr(PageStart+YStart);
1473    
1474     if (mask) { // DECCARA
1475     if (YStart == YEnd) {
1476     i = Ptr + XStart - 1;
1477     endp = Ptr + XEnd + 1;
1478    
1479 zmatsuo 8742 if (XStart > 0 && (CodeBuffW[i].attr & AttrKanji)) {
1480 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1481     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1482 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1483     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1484 doda 7086 }
1485     while (++i < endp) {
1486 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1487     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1488 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1489     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1490 doda 7086 }
1491 zmatsuo 8742 if (XEnd < NumOfColumns-1 && (CodeBuffW[i-1].attr & AttrKanji)) {
1492 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1493     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1494 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1495     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1496 doda 7086 }
1497     }
1498     else {
1499     i = Ptr + XStart - 1;
1500     endp = Ptr + NumOfColumns;
1501    
1502 zmatsuo 8742 if (XStart > 0 && (CodeBuffW[i].attr & AttrKanji)) {
1503 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1504     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1505 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1506     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1507 doda 7086 }
1508     while (++i < endp) {
1509 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1510     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1511 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1512     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1513 doda 7086 }
1514    
1515     for (j=0; j < YEnd-YStart-1; j++) {
1516     Ptr = NextLinePtr(Ptr);
1517     i = Ptr;
1518     endp = Ptr + NumOfColumns;
1519    
1520     while (i < endp) {
1521 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1522     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1523 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1524     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1525 doda 7086 i++;
1526     }
1527     }
1528    
1529     Ptr = NextLinePtr(Ptr);
1530     i = Ptr;
1531     endp = Ptr + XEnd + 1;
1532    
1533     while (i < endp) {
1534 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1535     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1536 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1537     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1538 doda 7086 i++;
1539     }
1540 zmatsuo 8742 if (XEnd < NumOfColumns-1 && (CodeBuffW[i-1].attr & AttrKanji)) {
1541 zmatsuo 10101 CodeBuffW[i].attr = (CodeBuffW[i].attr & ~mask->Attr) | attr->Attr;
1542     CodeBuffW[i].attr2 = (CodeBuffW[i].attr2 & ~mask->Attr2) | attr->Attr2;
1543 zmatsuo 8741 if (mask->Attr2 & Attr2Fore) { CodeBuffW[i].fg = attr->Fore; }
1544     if (mask->Attr2 & Attr2Back) { CodeBuffW[i].bg = attr->Back; }
1545 doda 7086 }
1546     }
1547     }
1548     else { // DECRARA
1549     if (YStart == YEnd) {
1550     i = Ptr + XStart - 1;
1551     endp = Ptr + XEnd + 1;
1552    
1553 zmatsuo 8742 if (XStart > 0 && (CodeBuffW[i].attr & AttrKanji)) {
1554     CodeBuffW[i].attr ^= attr->Attr;
1555 doda 7086 }
1556     while (++i < endp) {
1557 zmatsuo 8742 CodeBuffW[i].attr ^= attr->Attr;
1558 doda 7086 }
1559 zmatsuo 8742 if (XEnd < NumOfColumns-1 && (CodeBuffW[i-1].attr & AttrKanji)) {
1560     CodeBuffW[i].attr ^= attr->Attr;
1561 doda 7086 }
1562     }
1563     else {
1564     i = Ptr + XStart - 1;
1565     endp = Ptr + NumOfColumns;
1566    
1567 zmatsuo 8742 if (XStart > 0 && (CodeBuffW[i].attr & AttrKanji)) {
1568     CodeBuffW[i].attr ^= attr->Attr;
1569 doda 7086 }
1570     while (++i < endp) {
1571 zmatsuo 8742 CodeBuffW[i].attr ^= attr->Attr;
1572 doda 7086 }
1573    
1574     for (j=0; j < YEnd-YStart-1; j++) {
1575     Ptr = NextLinePtr(Ptr);
1576     i = Ptr;
1577     endp = Ptr + NumOfColumns;
1578    
1579     while (i < endp) {
1580 zmatsuo 8742 CodeBuffW[i].attr ^= attr->Attr;
1581 doda 7086 i++;
1582     }
1583     }
1584    
1585     Ptr = NextLinePtr(Ptr);
1586     i = Ptr;
1587     endp = Ptr + XEnd + 1;
1588    
1589     while (i < endp) {
1590 zmatsuo 8742 CodeBuffW[i].attr ^= attr->Attr;
1591 doda 7086 i++;
1592     }
1593 zmatsuo 8742 if (XEnd < NumOfColumns-1 && (CodeBuffW[i-1].attr & AttrKanji)) {
1594     CodeBuffW[i].attr ^= attr->Attr;
1595 doda 7086 }
1596     Ptr = NextLinePtr(Ptr);
1597     }
1598     }
1599     BuffUpdateRect(0, YStart, NumOfColumns-1, YEnd);
1600     }
1601    
1602 zmatsuo 10308 /**
1603     * (Line,CharPtr)���u���S�p���E��(��������N cell��1cell����������)����
1604     * ���������������u������
1605     *
1606     * If CharPtr is on the right half of a DBCS character
1607     * return pointer to the left half
1608     *
1609     * @param Line points to a line in CodeBuff
1610     * @param CharPtr points to a char
1611     * @return points to the left half of the DBCS
1612     */
1613 doda 8445 static int LeftHalfOfDBCS(LONG Line, int CharPtr)
1614 maya 3227 {
1615 zmatsuo 10308 int x = CharPtr;
1616     while(x > 0) {
1617     if ((CodeBuffW[Line+x].Padding) == FALSE) {
1618     // padding��������
1619     break;
1620     }
1621     assert(x > 0); // �s���� padding?
1622     x--;
1623 maya 3393 }
1624 zmatsuo 10308 return x;
1625 maya 3227 }
1626    
1627 doda 8445 static int MoveCharPtr(LONG Line, int *x, int dx)
1628 maya 3227 // move character pointer x by dx character unit
1629     // in the line specified by Line
1630     // Line: points to a line in CodeBuff
1631     // x: points to a character in the line
1632     // dx: moving distance in character unit (-: left, +: right)
1633 maya 3393 // One DBCS character is counted as one character.
1634 maya 3227 // The pointer stops at the beginning or the end of line.
1635     // Output
1636     // x: new pointer. x points to a SBCS character or
1637     // the left half of a DBCS character.
1638     // return: actual moving distance in character unit
1639     {
1640 maya 3393 int i;
1641 maya 3227
1642 maya 3393 *x = LeftHalfOfDBCS(Line,*x);
1643     i = 0;
1644     while (dx!=0) {
1645     if (dx>0) { // move right
1646 zmatsuo 8742 if ((CodeBuffW[Line+*x].attr & AttrKanji) != 0) {
1647 maya 3393 if (*x<NumOfColumns-2) {
1648     i++;
1649     *x = *x + 2;
1650     }
1651     }
1652     else if (*x<NumOfColumns-1) {
1653     i++;
1654     (*x)++;
1655     }
1656     dx--;
1657     }
1658     else { // move left
1659     if (*x>0) {
1660     i--;
1661     (*x)--;
1662     }
1663     *x = LeftHalfOfDBCS(Line,*x);
1664     dx++;
1665     }
1666 maya 3227 }
1667 maya 3393 return i;
1668 maya 3227 }
1669    
1670 doda 8445 /**
1671     * (�N���b�v�{�[�h�p��)������������
1672     * @param[in] sx,sy,ex,ey �I������
1673     * @param[in] box_select TRUE=���^(���`)�I��
1674     * FALSE=�s�I��
1675     * @param[out] _str_len ��������(�����[L'\0'������)
1676     * NULL����������������
1677     * @return ������
1678     * �g�p���� free() ��������
1679     */
1680     static wchar_t *BuffGetStringForCB(int sx, int sy, int ex, int ey, BOOL box_select, size_t *_str_len)
1681     {
1682     wchar_t *str_w;
1683     size_t str_size; // �m�������T�C�Y
1684     size_t k;
1685     LONG TmpPtr;
1686     int x, y;
1687    
1688 zmatsuo 10061 str_size = (NumOfColumns + 2) * (ey - sy + 1);
1689 doda 8445 str_w = malloc(sizeof(wchar_t) * str_size);
1690    
1691     LockBuffer();
1692    
1693     str_w[0] = 0;
1694     TmpPtr = GetLinePtr(sy);
1695     k = 0;
1696     for (y = sy; y<=ey ; y++) {
1697 zmatsuo 10030 int IStart; // �J�n
1698     int IEnd; // �I��
1699     BOOL LineContinued;
1700    
1701 doda 8445 if (box_select) {
1702 zmatsuo 10030 IStart = sx;
1703     IEnd = ex - 1;
1704     LineContinued = FALSE;
1705 doda 8445 }
1706     else {
1707 zmatsuo 10030 // �s�I��
1708     IStart = (y == sy) ? sx : 0;
1709 zmatsuo 10061 LineContinued = FALSE;
1710     if (y == ey) {
1711     // 1�s�I�����A����
1712     // �����s�I�������������s
1713     IEnd = ex - 1;
1714     }
1715     else {
1716     // �����s�I�������r�����s
1717     // �s�������I������������
1718     IEnd = NumOfColumns - 1;
1719 doda 8445
1720 zmatsuo 10061 // �p���s�R�s�[����
1721     if (ts.EnableContinuedLineCopy) {
1722     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1723     if ((CodeBuffW[NextTmpPtr].attr & AttrLineContinued) != 0) {
1724     // �����s���p����������
1725     LineContinued = TRUE;
1726     }
1727 doda 8445 }
1728     }
1729     }
1730    
1731 zmatsuo 10062 // IEnd=�R�s�[���K�v�����������u
1732     if (LineContinued) {
1733     // �s���������������R�s�[����
1734     IEnd++;
1735     }
1736     else {
1737 zmatsuo 10061 // �����s���p�����������������A�X�y�[�X����������
1738 zmatsuo 10030 while (IEnd >= IStart) {
1739     // �R�s�[�s�v��" "(0x20)������
1740 doda 8445 const buff_char_t *b = &CodeBuffW[TmpPtr + IEnd];
1741 zmatsuo 10030 if (b->u32 != 0x20) {
1742     // �X�y�[�X���O������
1743 zmatsuo 10062 IEnd++;
1744 zmatsuo 10030 break;
1745 doda 8445 }
1746 zmatsuo 10030 if (IEnd == 0) {
1747 doda 8445 break;
1748     }
1749 zmatsuo 10030 // �����l����
1750     MoveCharPtr(TmpPtr,&IEnd,-1);
1751 doda 8445 }
1752     }
1753    
1754 zmatsuo 10030 // 1���C�����������R�s�[����
1755 zmatsuo 10062 // IEnd=�R�s�[���K�v�����������u+1
1756 doda 8445 x = IStart;
1757 zmatsuo 10062 while (x < IEnd) {
1758 doda 8445 const buff_char_t *b = &CodeBuffW[TmpPtr + x];
1759     if (b->u32 != 0) {
1760     str_w[k++] = b->wc2[0];
1761     if (b->wc2[1] != 0) {
1762     str_w[k++] = b->wc2[1];
1763     }
1764     if (k + 2 >= str_size) {
1765     str_size *= 2;
1766     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
1767     }
1768     {
1769     int i;
1770     // �R���r�l�[�V����
1771     if (k + b->CombinationCharCount16 >= str_size) {
1772     str_size += + b->CombinationCharCount16;
1773     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
1774     }
1775     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
1776     str_w[k++] = b->pCombinationChars16[i];
1777     }
1778     }
1779     }
1780     x++;
1781     }
1782    
1783     if (y < ey) {
1784     // ���s��������(�������s���O������)
1785     if (!LineContinued) {
1786     str_w[k++] = 0x0d;
1787     str_w[k++] = 0x0a;
1788     }
1789     }
1790    
1791     TmpPtr = NextLinePtr(TmpPtr);
1792     }
1793     str_w[k++] = 0;
1794    
1795     UnlockBuffer();
1796    
1797     if (_str_len != NULL) {
1798     *_str_len = k;
1799     }
1800     return str_w;
1801     }
1802    
1803     /**
1804 zmatsuo 8678 * 1�Z������wchar_t���������W�J����
1805     * @param[in] b 1�Z�������������������|�C���^
1806     * @param[in,out] buf �������W�J�� NULL���������W�J��������
1807 zmatsuo 8744 * @param[in] buf_size buf��������(buff == NULL���������Q����������)
1808     * @param[out] too_small NULL ��������������������
1809     * TRUE �o�b�t�@�T�C�Y�s��
1810     * �����l���K�v��������������
1811     * FALSE �������W�J������
1812     * @retrun ������ �o��������
1813     * 0�������A�����o������
1814 zmatsuo 8745 *
1815     * TODO
1816     * GetWCS() ������?
1817 zmatsuo 8678 */
1818     static size_t expand_wchar(const buff_char_t *b, wchar_t *buf, size_t buf_size, BOOL *too_samll)
1819     {
1820     size_t len;
1821    
1822     if (IsBuffPadding(b)) {
1823     if (too_samll != NULL) {
1824     *too_samll = FALSE;
1825     }
1826     return 0;
1827     }
1828    
1829     // ����������
1830     len = 0;
1831     if (b->wc2[1] == 0) {
1832     // �T���Q�[�g�y�A��������
1833     len++;
1834     } else {
1835     // �T���Q�[�g�y�A
1836     len += 2;
1837     }
1838     // �R���r�l�[�V����
1839     len += b->CombinationCharCount16;
1840    
1841     if (buf == NULL) {
1842     // ��������������
1843     return len;
1844     }
1845    
1846     // �o�b�t�@��������?
1847     if (len > buf_size) {
1848     // �o�b�t�@������������
1849     if (too_samll != NULL) {
1850     *too_samll = TRUE;
1851     }
1852 zmatsuo 8908 return len;
1853 zmatsuo 8678 }
1854     if (too_samll != NULL) {
1855     *too_samll = FALSE;
1856     }
1857    
1858     // �W�J��������
1859     *buf++ = b->wc2[0];
1860     if (b->wc2[1] != 0) {
1861     *buf++ = b->wc2[1];
1862     }
1863     if (b->CombinationCharCount16 != 0) {
1864     memcpy(buf, b->pCombinationChars16, b->CombinationCharCount16 * sizeof(wchar_t));
1865     }
1866    
1867     return len;
1868     }
1869    
1870     /**
1871 doda 8445 * (x,y) ��1������ str��������������
1872     * *�� 1������������wchar_t�����\������������
1873     *
1874 zmatsuo 8744 * @param b
1875     * @param str ���r������(wchar_t)
1876     * @param len ���r��������
1877     * @retval �}�b�`������������
1878     * 0=�}�b�`����������
1879 doda 8445 */
1880 zmatsuo 8744 static size_t MatchOneStringPtr(const buff_char_t *b, const wchar_t *str, size_t len)
1881 doda 8445 {
1882 zmatsuo 8747 int match_pos = 0;
1883 zmatsuo 8744 if (len == 0) {
1884     return 0;
1885     }
1886 doda 8445 if (b->wc2[1] == 0) {
1887     // �T���Q�[�g�y�A��������
1888     if (str[match_pos] != b->wc2[0]) {
1889     return 0;
1890     }
1891     match_pos++;
1892     len--;
1893     } else {
1894     // �T���Q�[�g�y�A
1895     if (len < 2) {
1896     return 0;
1897     }
1898     if (str[match_pos+0] != b->wc2[0] ||
1899     str[match_pos+1] != b->wc2[1]) {
1900     return 0;
1901     }
1902     match_pos+=2;
1903     len-=2;
1904     }
1905     if (b->CombinationCharCount16 > 0) {
1906     // �R���r�l�[�V����
1907     int i;
1908     if (len < b->CombinationCharCount16) {
1909     return 0;
1910     }
1911     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
1912     if (str[match_pos++] != b->pCombinationChars16[i]) {
1913     return 0;
1914     }
1915     }
1916     len -= b->CombinationCharCount16;
1917     }
1918     return match_pos;
1919     }
1920    
1921     /**
1922 zmatsuo 8744 * (x,y) ��1������ str��������������
1923     * *�� 1������������wchar_t�����\������������
1924     *
1925     * @param y PageStart + CursorY
1926     * @param str 1����(wchar_t��)
1927     * @param len ��������
1928     * @retval 0=�}�b�`����������
1929     * �}�b�`������������
1930     */
1931     static size_t MatchOneString(int x, int y, const wchar_t *str, size_t len)
1932     {
1933     int TmpPtr = GetLinePtr(y);
1934     const buff_char_t *b = &CodeBuffW[TmpPtr + x];
1935     return MatchOneStringPtr(b, str, len);
1936     }
1937    
1938     /**
1939     * b ���� str��������������
1940     *
1941     * @param b �o�b�t�@�����|�C���^�A����������������
1942     * @param LineCntinued TRUE=�s���p�����l������
1943     * @retval TRUE �}�b�`����
1944     * @retval FALSE �}�b�`����������
1945     */
1946 zmatsuo 10311 #if 0
1947 zmatsuo 8744 static BOOL MatchStringPtr(const buff_char_t *b, const wchar_t *str, BOOL LineContinued)
1948     {
1949     int x;
1950     int y;
1951     BOOL result;
1952     size_t len = wcslen(str);
1953     if (len == 0) {
1954     return FALSE;
1955     }
1956     GetPosFromPtr(b, &x, &y);
1957     for(;;) {
1958 zmatsuo 8747 size_t match_len;
1959 zmatsuo 8744 if (IsBuffPadding(b)) {
1960     b++;
1961     continue;
1962     }
1963     // 1����������������
1964 zmatsuo 8747 match_len = MatchOneString(x, y, str, len);
1965 zmatsuo 8744 if (match_len == 0) {
1966     result = FALSE;
1967     break;
1968     }
1969     len -= match_len;
1970     if (len == 0) {
1971     // �S���������I������
1972     result = TRUE;
1973     break;
1974     }
1975     str += match_len;
1976    
1977     // ��������
1978     x++;
1979     if (x == NumOfColumns) {
1980     if (LineContinued && ((b->attr & AttrLineContinued) != 0)) {
1981     // �����s��
1982     y++;
1983     if (y == NumOfLines) {
1984     // �o�b�t�@���I�[
1985     return 0;
1986     }
1987     x = 0;
1988     b = &CodeBuffW[GetLinePtr(y)];
1989     } else {
1990     // �s��
1991     result = FALSE;
1992     break;
1993     }
1994     }
1995     }
1996    
1997     return result;
1998     }
1999 zmatsuo 10311 #endif
2000 zmatsuo 8744
2001     /**
2002 doda 8445 * (x,y)���� str��������������
2003     *
2004     * @param x �}�C�i�X�����A�����s������������
2005     * @param y PageStart + CursorY
2006     * @param LineCntinued TRUE=�s���p�����l������
2007     * @retval TRUE �}�b�`����
2008     * @retval FALSE �}�b�`����������
2009     */
2010     static BOOL MatchString(int x, int y, const wchar_t *str, BOOL LineContinued)
2011     {
2012     BOOL result;
2013     int TmpPtr = GetLinePtr(y);
2014     size_t len = wcslen(str);
2015     if (len == 0) {
2016     return FALSE;
2017     }
2018     while(x < 0) {
2019 zmatsuo 8742 if (LineContinued && (CodeBuffW[TmpPtr+0].attr & AttrLineContinued) == 0) {
2020 doda 8445 // �s���p�������������l�� & �p������������
2021     x = 0; // �s������������
2022     break;
2023     }
2024     TmpPtr = PrevLinePtr(TmpPtr);
2025     x += NumOfColumns;
2026     y--;
2027     }
2028     while(x > NumOfColumns) {
2029 zmatsuo 8742 if (LineContinued && (CodeBuffW[TmpPtr+NumOfColumns-1].attr & AttrLineContinued) == 0) {
2030 doda 8445 // �s���p�������������l�� & �p������������
2031     x = 0; // �s������������
2032     break;
2033     }
2034     TmpPtr = NextLinePtr(TmpPtr);
2035     x -= NumOfColumns;
2036     }
2037    
2038     for(;;) {
2039     // 1����������������
2040     size_t match_len = MatchOneString(x, y, str, len);
2041     if (match_len == 0) {
2042     result = FALSE;
2043     break;
2044     }
2045     len -= match_len;
2046     if (len == 0) {
2047     // �S���������I������
2048     result = TRUE;
2049     break;
2050     }
2051     str += match_len;
2052    
2053     // ��������
2054     x++;
2055     if (x == NumOfColumns) {
2056 zmatsuo 8742 if (LineContinued && (CodeBuffW[TmpPtr+NumOfColumns-1].attr & AttrLineContinued) != 0) {
2057 doda 8445 // �����s��
2058     x = 0;
2059     TmpPtr = NextLinePtr(TmpPtr);
2060     y++;
2061     } else {
2062     // �s��
2063     result = FALSE;
2064     break;
2065     }
2066     }
2067     }
2068    
2069     return result;
2070     }
2071    
2072     /**
2073     * (sx,sy)����(ex,ey)������ str ���}�b�`�����������T����
2074     * ���u������
2075     *
2076     * @param sy,ex PageStart + CursorY
2077     * @param[out] x �}�b�`�������u
2078     * @param[out] y �}�b�`�������u
2079     * @retval TRUE �}�b�`����
2080     */
2081     static BOOL BuffGetMatchPosFromString(
2082     int sx, int sy, int ex, int ey, const wchar_t *str,
2083     int *match_x, int *match_y)
2084     {
2085     int IStart, IEnd;
2086     int x, y;
2087    
2088     for (y = sy; y<=ey ; y++) {
2089     IStart = 0;
2090     IEnd = NumOfColumns-1;
2091     if (y== sy) {
2092     IStart = sx;
2093     }
2094     if (y== ey) {
2095     IEnd = ex;
2096     }
2097    
2098     x = IStart;
2099     while (x <= IEnd) {
2100     if (MatchString(x, y, str, TRUE)) {
2101     // �}�b�`����
2102     if (match_x != NULL) {
2103     *match_x = x;
2104     }
2105     if (match_y != NULL) {
2106     *match_y = y;
2107     }
2108     return TRUE;
2109     }
2110     x++;
2111     }
2112     }
2113     return FALSE;
2114     }
2115    
2116    
2117     /**
2118     * �A�������X�y�[�X���^�u1�����u������
2119     * @param[out] _str_len ��������(L'\0'������)
2120     * @return ������
2121     * �g�p���� free() ��������
2122     */
2123     static wchar_t *ConvertTable(const wchar_t *src, size_t src_len, size_t *str_len)
2124     {
2125     wchar_t *dest_top = malloc(sizeof(wchar_t) * src_len);
2126     wchar_t *dest = dest_top;
2127     BOOL WhiteSpace = FALSE;
2128     while (*src != '\0') {
2129     wchar_t c = *src++;
2130     if (c == 0x0d || c == 0x0a) {
2131     *dest++ = c;
2132     WhiteSpace = FALSE;
2133     } else if (c <= L' ') {
2134     if (!WhiteSpace) {
2135     // insert tab
2136     *dest++ = 0x09;
2137     WhiteSpace = TRUE;
2138     }
2139     } else {
2140     *dest++ = c;
2141     WhiteSpace = FALSE;
2142     }
2143     }
2144     *dest = L'\0';
2145     *str_len = dest - dest_top + 1;
2146     return dest_top;
2147     }
2148    
2149    
2150 zmatsuo 8676 /**
2151     * �N���b�v�{�[�h�p����������
2152     * @return ������
2153     * �g�p���� free() ��������
2154     */
2155     wchar_t *BuffCBCopyUnicode(BOOL Table)
2156 doda 8445 {
2157     wchar_t *str_ptr;
2158     size_t str_len;
2159     str_ptr = BuffGetStringForCB(
2160     SelectStart.x, SelectStart.y,
2161     SelectEnd.x, SelectEnd.y, BoxSelect,
2162     &str_len);
2163    
2164     // �e�[�u���`��������
2165     if (Table) {
2166     size_t table_len;
2167     wchar_t *table_ptr = ConvertTable(str_ptr, str_len, &table_len);
2168     free(str_ptr);
2169     str_ptr = table_ptr;
2170     str_len = table_len;
2171     }
2172 zmatsuo 8676 return str_ptr;
2173 doda 8445 }
2174    
2175 maya 3227 void BuffPrint(BOOL ScrollRegion)
2176     // Print screen or selected text
2177     {
2178 maya 3393 int Id;
2179     POINT PrintStart, PrintEnd;
2180 zmatsuo 9040 int j;
2181 maya 3393 int IStart, IEnd;
2182     LONG TmpPtr;
2183 maya 3227
2184 maya 3393 if (ScrollRegion) {
2185     Id = VTPrintInit(IdPrnScrollRegion);
2186     }
2187     else if (Selected) {
2188     Id = VTPrintInit(IdPrnScreen | IdPrnSelectedText);
2189     }
2190     else {
2191     Id = VTPrintInit(IdPrnScreen);
2192     }
2193     if (Id==IdPrnCancel) {
2194     return;
2195     }
2196 maya 3227
2197 maya 3393 /* set print region */
2198     if (Id==IdPrnSelectedText) {
2199     /* print selected region */
2200     PrintStart = SelectStart;
2201     PrintEnd = SelectEnd;
2202     }
2203     else if (Id==IdPrnScrollRegion) {
2204     /* print scroll region */
2205     PrintStart.x = 0;
2206     PrintStart.y = PageStart + CursorTop;
2207     PrintEnd.x = NumOfColumns;
2208     PrintEnd.y = PageStart + CursorBottom;
2209     }
2210     else {
2211     /* print current screen */
2212     PrintStart.x = 0;
2213     PrintStart.y = PageStart;
2214     PrintEnd.x = NumOfColumns;
2215     PrintEnd.y = PageStart + NumOfLines - 1;
2216     }
2217     if (PrintEnd.y > BuffEnd-1) {
2218     PrintEnd.y = BuffEnd-1;
2219     }
2220 maya 3227
2221 maya 3393 LockBuffer();
2222 maya 3227
2223 maya 3393 TmpPtr = GetLinePtr(PrintStart.y);
2224     for (j = PrintStart.y ; j <= PrintEnd.y ; j++) {
2225     if (j==PrintStart.y) {
2226     IStart = PrintStart.x;
2227     }
2228     else {
2229     IStart = 0;
2230     }
2231     if (j == PrintEnd.y) {
2232     IEnd = PrintEnd.x - 1;
2233     }
2234     else {
2235     IEnd = NumOfColumns - 1;
2236     }
2237 maya 3227
2238 zmatsuo 9040 BuffDrawLineIPrn(j, IStart, IEnd);
2239 maya 3393 PrnNewLine();
2240     TmpPtr = NextLinePtr(TmpPtr);
2241     }
2242 maya 3227
2243 maya 3393 UnlockBuffer();
2244     VTPrintEnd();
2245 maya 3227 }
2246    
2247 zmatsuo 8744 // TODO ���������� ANSI ������
2248 maya 3227 // Dumps current line to the file (for path through printing)
2249     // HFile: file handle
2250     // TERM: terminator character
2251     // = LF or VT or FF
2252 zmatsuo 9115 void BuffDumpCurrentLine(PrintFile *handle, BYTE TERM)
2253 maya 3227 {
2254 maya 3393 int i, j;
2255 zmatsuo 8744 buff_char_t *b = &CodeBuffW[LinePtr];
2256     char bufA[TermWidthMax+1];
2257     char *p = bufA;
2258 maya 3227
2259 maya 3393 i = NumOfColumns;
2260 zmatsuo 8744 while ((i>0) && (b[i-1].ansi_char == 0x20)) {
2261 maya 3393 i--;
2262     }
2263 zmatsuo 8744 p = bufA;
2264 maya 3393 for (j=0; j<i; j++) {
2265 zmatsuo 8744 unsigned short c = b[j].ansi_char;
2266     *p++ = (c & 0xff);
2267     if (c > 0x100) {
2268     *p++ = (c & 0xff);
2269     }
2270 maya 3393 }
2271 zmatsuo 8744 p = bufA;
2272     for (j=0; j<i; j++) {
2273 zmatsuo 9115 WriteToPrnFile(handle, bufA[j],FALSE);
2274 zmatsuo 8744 }
2275 zmatsuo 9115 WriteToPrnFile(handle, 0,TRUE);
2276 maya 3393 if ((TERM>=LF) && (TERM<=FF)) {
2277 zmatsuo 9115 WriteToPrnFile(handle, 0x0d,FALSE);
2278     WriteToPrnFile(handle, TERM,TRUE);
2279 maya 3393 }
2280 maya 3227 }
2281    
2282 doda 8445 static BOOL isURLchar(unsigned int u32)
2283     {
2284     // RFC3986(Uniform Resource Identifier (URI): Generic Syntax)����������
2285     // by sakura editor 1.5.2.1: etc_uty.cpp
2286     static const char url_char[] = {
2287     /* +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F */
2288