Bug 519376 - The Chinese wide char could not showed accurately when the ncurses Window is refresehd
Summary: The Chinese wide char could not showed accurately when the ncurses Window is ...
Keywords:
Status: CLOSED INSUFFICIENT_DATA
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: ncurses
Version: 5.3
Hardware: All
OS: Linux
high
medium
Target Milestone: rc
: ---
Assignee: Miroslav Lichvar
QA Contact: BaseOS QE
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2009-08-26 11:59 UTC by Miroslav Lichvar
Modified: 2018-11-14 17:59 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of: 519311
Environment:
Last Closed: 2011-10-16 18:48:52 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
fix for refresh of window on top of multi-column characters (7.07 KB, patch)
2009-08-26 12:40 UTC, Miroslav Lichvar
no flags Details | Diff
testing examples codes that can demonstrate the issues (763 bytes, application/x-gzip)
2009-11-30 01:57 UTC, Qianfeng Zhang
no flags Details

Description Miroslav Lichvar 2009-08-26 11:59:10 UTC
+++ This bug was initially created as a clone of Bug #519311 +++

See that attached testC.c file.   Compiled with "#> gcc -o testC testC.c -lncursesw"  

With the codes,  the second ncurses window  "pWin1" will exactly cover the righ half of the second Chinese word in the string. But after popping up "pWin1",  the 
"wnoutrefresh(pWin)" and "doupdate()"  could not recover the content of string correctly. 

I have checked the codes and made a patch to fix the issue.  Here attached the patches for both  ncurses-5.4-15/RHEL4.8 and ncurses-5.5.26/RHEL5.3.


The point with the patching is that: 

     In  doupdate()/TransformLine(),  we have to re-print the whole wide char even though only half of the char was covered, cause the codes in PutAttrChar() always ignore the extended half of the wide char (and not print it to the stdout) ;  and some terminal (eg. gnome-terminal) could not redraw the Wide Char if not the whole bytes of it were received from the pipe each time.

--- Additional comment from frzhang on 2009-08-25 22:11:21 EDT ---

Created an attachment (id=358657)
Testing code

--- Additional comment from frzhang on 2009-08-25 22:16:18 EDT ---

Created an attachment (id=358658)
patch for  ncurses-5.4-15/RHEL4.7

--- Additional comment from frzhang on 2009-08-25 22:17:09 EDT ---

Created an attachment (id=358659)
patch for ncurses-5.5-26/RHEL5.3

--- Additional comment from mlichvar on 2009-08-26 06:51:12 EDT ---

This seems to be fixed in upstream patches 20070630 and 20070707:

20070707
       + improve fix for refresh of window on top of multi-column characters,
         taking into account some split characters on left/right window
         boundaries.

20070630
       + partial fix for refresh of window on top of multi-column characters
         which are partly overwritten (report by Sadrul H Chowdhury).

Comment 1 Miroslav Lichvar 2009-08-26 12:40:23 UTC
Created attachment 358708 [details]
fix for refresh of window on top of multi-column characters

Comment 3 RHEL Program Management 2009-11-06 18:50:47 UTC
This request was evaluated by Red Hat Product Management for
inclusion, but this component is not scheduled to be updated in
the current Red Hat Enterprise Linux release. If you would like
this request to be reviewed for the next minor release, ask your
support representative to set the next rhel-x.y flag to "?".

Comment 4 Qianfeng Zhang 2009-11-08 07:56:11 UTC
Several issues reported again by my customer, so a simple fix is not enough. I made a bigger patch for  ncurses-5.5-26.  The patch does the following: 
 1) added PutChar2() to print an isolated Wchar "Ext" as a blank
 2) adjust in EmitRange() so that isolated Wchar "Base" and "Ext" be printed as blanks
 3) adjust in TransformLine() so that Wchar "Base" right before "first char" and Wchar "Ext" right after "last char" be included into PutRange()

Comment 5 Qianfeng Zhang 2009-11-08 08:04:22 UTC
--- old/ncurses/tty/tty_update.c        2009-11-07 18:36:16.000000000 +0800
+++ new/ncurses/tty/tty_update.c        2009-11-07 19:02:36.000000000 +0800
@@ -439,6 +439,30 @@
     position_check(SP->_cursrow, SP->_curscol, "PutChar");
 }

+#if USE_WIDEC_SUPPORT
+/* need PutChar2() to print an isolated wide char "Ext" as a blank */
+static NCURSES_INLINE void
+PutChar2(const ARG_CH_T ch, int lastIsWcharBase)
+/* insert character, handling automargin stuff */
+{
+    static const NCURSES_CH_T blank = NewChar(BLANK_TEXT);
+
+    if ( !lastIsWcharBase && isWidecExt(CHDEREF(ch)) ) 
+         ch  = CHREF(blank) ; 
+
+    if (SP->_cursrow == screen_lines - 1 && SP->_curscol == screen_columns - 1)
+        PutCharLR(ch);
+    else
+        PutAttrChar(ch);
+
+    if (SP->_curscol >= screen_columns)
+        wrap_cursor();
+
+    position_check(SP->_cursrow, SP->_curscol, "PutChar");
+}
+
+#endif
+
 /*
  * Check whether the given character can be output by clearing commands.  This
  * includes test for being a space and not including any 'bad' attributes, such
@@ -487,6 +511,10 @@
 EmitRange(const NCURSES_CH_T * ntext, int num)
 {
     int i;
+#if USE_WIDEC_SUPPORT
+    int  lastIsWcharBase=0;
+    static const NCURSES_CH_T myBlank = NewChar(BLANK_TEXT);
+#endif

     TR(TRACE_CHARPUT, ("EmitRange %d:%s", num, _nc_viscbuf(ntext, num)));

@@ -496,13 +524,38 @@
            NCURSES_CH_T ntext0;

            while (num > 1 && !CharEq(ntext[0], ntext[1])) {
-               PutChar(CHREF(ntext[0]));
+#if USE_WIDEC_SUPPORT
+                /* print isolated Wchar "Base" as a blank */
+                if ( isWidecBase(ntext[0]) && ! isWidecExt(ntext[1]) ) 
+                     PutChar(CHREF(myBlank));
+                else
+                     PutChar2(CHREF(ntext[0]), lastIsWcharBase); 
+
+                if ( isWidecBase(ntext[0]) )
+                     lastIsWcharBase = 1;
+                else
+                     lastIsWcharBase = 0;
+#else
+                PutChar(CHREF(ntext[0]));
+#endif
                ntext++;
                num--;
            }
            ntext0 = ntext[0];
            if (num == 1) {
-               PutChar(CHREF(ntext0));
+#if USE_WIDEC_SUPPORT
+                /* print isolated Wchar "Base" as a blank */
+                if ( isWidecBase(ntext[0]) )
+                     PutChar(CHREF(myBlank));
+                else
+                     PutChar2(CHREF(ntext[0]), lastIsWcharBase);
+                if ( isWidecBase(ntext[0]) )
+                     lastIsWcharBase = 1;
+                else
+                     lastIsWcharBase = 0;
+#else
+                PutChar(CHREF(ntext[0]));
+#endif
                return 0;
            }
            runcount = 2;
@@ -549,8 +602,22 @@
                if (wrap_possible)
                    PutChar(CHREF(ntext0));
            } else {
-               for (i = 0; i < runcount; i++)
-                   PutChar(CHREF(ntext[i]));
+               for (i = 0; i < runcount; i++) {
+#if USE_WIDEC_SUPPORT
+                    /* print isolated Wchar "Base" as a blank */
+                    if ( (i< runcount-1) && isWidecBase(ntext[i]) && ! isWidecExt(ntext[i+1]) )
+                         PutChar(CHREF(myBlank));
+                    else
+                         PutChar2(CHREF(ntext[i]), lastIsWcharBase);
+
+                    if ( isWidecBase(ntext[i]) )                
+                         lastIsWcharBase = 1;
+                    else
+                         lastIsWcharBase = 0;
+#else
+                    PutChar(CHREF(ntext[i]));
+#endif
+                }
            }
            ntext += runcount;
            num -= runcount;
@@ -558,8 +625,22 @@
        return 0;
     }

-    for (i = 0; i < num; i++)
+    for (i = 0; i < num; i++) {
+#if USE_WIDEC_SUPPORT
+        /* print isolated Wchar "Base" as a blank */
+        if ( (i< num-1) && isWidecBase(ntext[i]) && ! isWidecExt(ntext[i+1]) )
+             PutChar(CHREF(myBlank));
+        else
+             PutChar2(CHREF(ntext[i]), lastIsWcharBase);
+
+        if ( isWidecBase(ntext[i]) ) 
+             lastIsWcharBase = 1;
+        else
+             lastIsWcharBase = 0;
+#else
        PutChar(CHREF(ntext[i]));
+#endif
+    }
     return 0;
 }

@@ -1285,6 +1366,12 @@
            return;
        }

+#if USE_WIDEC_SUPPORT
+        /* don't let alone a Wchar "Base", even it may be isolated */ 
+        if ( ( firstChar > 0 ) && isWidecBase(newLine[firstChar-1]) ) 
+               firstChar--; 
+#endif
+
        blank = newLine[screen_columns - 1];

        if (!can_clear_with(CHREF(blank))) {
@@ -1295,6 +1382,11 @@
                   && CharEq(newLine[nLastChar], oldLine[nLastChar]))
                nLastChar--;

+#if USE_WIDEC_SUPPORT
+                /* don't let alone a Wchar "Ext", even it may be isolated */
+                if ( ( nLastChar < screen_columns -1 ) &&  isWidecExt(newLine[nLastChar+1]) )
+                     nLastChar++;
+#endif 
            if (nLastChar >= firstChar) {
                GoTo(lineno, firstChar);
                PutRange(oldLine, newLine, lineno, firstChar, nLastChar);

Comment 6 Qianfeng Zhang 2009-11-30 01:57:41 UTC
Created attachment 374659 [details]
testing examples codes that can demonstrate the issues

The fixed packages have to make the attached examples work.  The "chinese words" in the codes are in "GB18030" .

Comment 7 Qianfeng Zhang 2009-11-30 02:07:29 UTC
I made no fix for ncurses-5.4-15/RHEL4.7.  But we can re-compiled the fixed ncurses-5.5-26 on RHEL4.7 and it works well.

Comment 8 Thomas E. Dickey 2010-04-24 21:05:53 UTC
I just noticed this followup last week.  The test-cases
appear to work with ncurses 5.7 (tested with 20100313).
If there are remaining issues with current ncurses code,
it would help to open a separate bug report to cover that.

Comment 10 RHEL Program Management 2010-08-09 18:40:25 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.

Comment 12 RHEL Program Management 2011-01-11 21:07:53 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.

Comment 13 RHEL Program Management 2011-01-11 23:07:21 UTC
This request was erroneously denied for the current release of
Red Hat Enterprise Linux.  The error has been fixed and this
request has been re-proposed for the current release.

Comment 14 RHEL Program Management 2011-05-31 13:44:02 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.

Comment 15 RHEL Program Management 2011-09-23 00:18:58 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated in the
current release, Red Hat is unfortunately unable to address this
request at this time. Red Hat invites you to ask your support
representative to propose this request, if appropriate and relevant,
in the next release of Red Hat Enterprise Linux.


Note You need to log in before you can comment on or make changes to this bug.