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 10308 - (hide annotations) (download) (as text)
Thu Oct 13 14:26:30 2022 UTC (17 months, 4 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 137640 byte(s)
Unicode の Spacing combining mark に一部対応

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