A new option is added, called "cjkwidth [on|off]". When it

is enabled, it treats CJK ambiguous characters as full width.
This feature is very helpful for reading legacy CJK applications'
output which assume all CJK characters are full width.
This option is default off.

The patch is obtained from
http://www.mhsin.org/~mhsin/patches/screen/patch-cjkwidth
The credit belongs to Michael Hsin <mhsin _at mhsin.org>.
It also has been submitted to upstream:
http://savannah.gnu.org/bugs/?func=detailitem&item_id=16666

PR:		ports/96167
Submitted by:	rafan
Approved by:	maintainer timeout (3 months and 2 weeks)
This commit is contained in:
Rong-En Fan 2006-08-05 16:40:17 +00:00
parent 796b49530f
commit 8721a6c9a0
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=169764
2 changed files with 232 additions and 0 deletions

View File

@ -40,6 +40,11 @@ CFLAGS+= -DCOLORS256
CFLAGS+= -DNONETHACK
.endif
# treat CJK ambiguous characters as full width via option "cjkwidth"
.if defined(WITH_CJK)
EXTRA_PATCHES+= ${.CURDIR}/files/opt-cjkwidth
.endif
post-patch:
@${RM} ${WRKSRC}/doc/screen.info*

View File

@ -0,0 +1,227 @@
--- ansi.c.orig Tue Jun 17 08:00:47 2003
+++ ansi.c Wed Jun 18 00:55:21 2003
@@ -701,7 +701,7 @@
curr->w_rend.font = 0;
}
# ifdef DW_CHARS
- if (curr->w_encoding == UTF8 && c >= 0x1100 && utf8_isdouble(c))
+ if (curr->w_encoding == UTF8 && utf8_isdouble(c))
curr->w_mbcs = 0xff;
# endif
if (curr->w_encoding == UTF8 && c >= 0x0300 && utf8_iscomb(c))
--- comm.c.orig Mon Sep 8 22:25:08 2003
+++ comm.c Fri May 6 19:06:12 2005
@@ -112,6 +112,9 @@
#endif
{ "charset", NEED_FORE|ARGS_1 },
{ "chdir", ARGS_01 },
+#ifdef DW_CHARS
+ { "cjkwidth", ARGS_01 },
+#endif
{ "clear", NEED_FORE|ARGS_0 },
{ "colon", NEED_LAYER|ARGS_01 },
{ "command", NEED_DISPLAY|ARGS_02 },
--- encoding.c.orig Mon Sep 8 22:25:23 2003
+++ encoding.c Fri May 6 20:05:24 2005
@@ -35,6 +35,10 @@
extern char *screenencodings;
+#ifdef DW_CHARS
+extern int cjkwidth;
+#endif
+
static int encmatch __P((char *, char *));
# ifdef UTF8
static int recode_char __P((int, int, int));
@@ -845,22 +849,107 @@
}
#ifdef DW_CHARS
+struct interval {
+ int first;
+ int last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(int ucs, const struct interval *table, int max) {
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
int
utf8_isdouble(c)
int c;
{
- return
- (c >= 0x1100 &&
- (c <= 0x115f || /* Hangul Jamo init. consonants */
- (c >= 0x2e80 && c <= 0xa4cf && (c & ~0x0011) != 0x300a &&
- c != 0x303f) || /* CJK ... Yi */
- (c >= 0xac00 && c <= 0xd7a3) || /* Hangul Syllables */
- (c >= 0xdf00 && c <= 0xdfff) || /* dw combining sequence */
- (c >= 0xf900 && c <= 0xfaff) || /* CJK Compatibility Ideographs */
- (c >= 0xfe30 && c <= 0xfe6f) || /* CJK Compatibility Forms */
- (c >= 0xff00 && c <= 0xff5f) || /* Fullwidth Forms */
- (c >= 0xffe0 && c <= 0xffe6) ||
- (c >= 0x20000 && c <= 0x2ffff)));
+ /* sorted list of non-overlapping intervals of East Asian Ambiguous
+ * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+ static const struct interval ambiguous[] = {
+ { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+ { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
+ { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+ { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+ { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+ { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+ { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+ { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+ { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+ { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+ { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+ { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+ { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+ { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+ { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+ { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
+ { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
+ { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
+ { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
+ { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
+ { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
+ { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
+ { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
+ { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
+ { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+ { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+ { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
+ { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
+ { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+ { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
+ { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
+ { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
+ { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
+ { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
+ { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
+ { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
+ { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
+ { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
+ { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
+ { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
+ { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
+ { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
+ { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
+ { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
+ { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
+ { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
+ { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
+ { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
+ { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
+ { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
+ { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
+ { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
+ };
+
+ return ((c >= 0x1100 &&
+ (c <= 0x115f || /* Hangul Jamo init. consonants */
+ c == 0x2329 || c == 0x232a ||
+ (c >= 0x2e80 && c <= 0xa4cf &&
+ c != 0x303f) || /* CJK ... Yi */
+ (c >= 0xac00 && c <= 0xd7a3) || /* Hangul Syllables */
+ (c >= 0xf900 && c <= 0xfaff) || /* CJK Compatibility Ideographs */
+ (c >= 0xfe30 && c <= 0xfe6f) || /* CJK Compatibility Forms */
+ (c >= 0xff00 && c <= 0xff60) || /* Fullwidth Forms */
+ (c >= 0xffe0 && c <= 0xffe6) ||
+ (c >= 0x20000 && c <= 0x2fffd) ||
+ (c >= 0x30000 && c <= 0x3fffd))) ||
+ (cjkwidth &&
+ bisearch(c, ambiguous,
+ sizeof(ambiguous) / sizeof(struct interval) - 1)));
}
#endif
--- process.c.orig Thu Sep 18 20:53:54 2003
+++ process.c Fri May 6 19:43:53 2005
@@ -103,6 +103,9 @@
#ifdef UTF8
extern char *screenencodings;
#endif
+#ifdef DW_CHARS
+extern int cjkwidth;
+#endif
static int CheckArgNum __P((int, char **));
static void ClearAction __P((struct action *));
@@ -3821,6 +3824,15 @@
Msg(0, "idle off");
}
break;
+#ifdef DW_CHARS
+ case RC_CJKWIDTH:
+ if(ParseSwitch(act, &cjkwidth) == 0)
+ {
+ if(msgok)
+ Msg(0, "Treat ambiguous width characters as %s width", cjkwidth ? "full" : "half");
+ }
+ break;
+#endif
default:
#ifdef HAVE_BRAILLE
/* key == -2: input from braille keybord, msgok always 0 */
--- screen.c.orig Mon Sep 8 22:26:41 2003
+++ screen.c Sat May 7 05:16:38 2005
@@ -221,6 +221,10 @@
char *screenencodings;
#endif
+#ifdef DW_CHARS
+int cjkwidth;
+#endif
+
#ifdef NETHACK
int nethackflag = 0;
#endif
@@ -468,6 +472,9 @@
InitBuiltinTabs();
screenencodings = SaveStr(SCREENENCODINGS);
#endif
+#ifdef DW_CHARS
+ cjkwidth = 0;
+#endif
nwin = nwin_undef;
nwin_options = nwin_undef;
strcpy(screenterm, "screen");
@@ -762,6 +769,19 @@
debug1("environment says encoding=%d\n", nwin_options.encoding);
#endif
}
+# ifdef DW_CHARS
+ {
+ char *s;
+ if((s = getenv("LC_ALL")) || (s = getenv("LC_CTYPE")) ||
+ (s = getenv("LANG")))
+ {
+ if(!strncmp(s, "zh_", 3) || !strncmp(s, "ja_", 3) || !strncmp(s, "ko_", 3))
+ {
+ cjkwidth = 1;
+ }
+ }
+ }
+#endif
#endif
if (SockMatch && strlen(SockMatch) >= MAXSTR)
Panic(0, "Ridiculously long socketname - try again.");