charsets.c revision 04b94745
1/* $XTermId: charsets.c,v 1.126 2024/05/22 00:27:53 tom Exp $ */ 2 3/* 4 * Copyright 1998-2023,2024 by Thomas E. Dickey 5 * 6 * All Rights Reserved 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name(s) of the above copyright 28 * holders shall not be used in advertising or otherwise to promote the 29 * sale, use or other dealings in this Software without prior written 30 * authorization. 31 * 32 */ 33 34#include <assert.h> 35#include <X11/keysym.h> 36 37#include <xterm.h> 38#include <data.h> 39#include <charsets.h> 40#include <fontutils.h> 41 42/* 43 * This module performs translation as needed to support the DEC VT220 national 44 * replacement character sets as well as supplementary character sets (aka 45 * code-pages) introduced in VT320, etc. 46 * 47 * We assume that xterm's font is based on the ISO 8859-1 (Latin 1) character 48 * set, which is almost the same as the DEC multinational character set. Glyph 49 * positions 0-31 have to be the DEC graphic characters, though. 50 * 51 * References: 52 * "VT220 Programmer Pocket Guide" EK-VT220-HR-002 (2nd ed., 1984), which 53 * contains character charts for the national character sets. 54 * "VT330/VT340 Programmer Reference Manual Volume 1: Text Programming" 55 * EK-VT3XX-TP-001 (1st ed, 1987), which contains a table (2-1) 56 * listing the glyphs which are mapped from the multinational 57 * character set to the national character set. 58 * 59 * The latter reference, though easier to read, has a few errors and omissions. 60 */ 61 62#define HandleUPSS(charset) \ 63 if (charset == nrc_DEC_UPSS) { \ 64 charset = screen->gsets_upss; \ 65 if (screen->vtXX_level >= 5) { \ 66 /* EMPTY */ ; \ 67 } else if (screen->vtXX_level >= 3) { \ 68 if (charset != nrc_DEC_Supp) \ 69 charset = nrc_ISO_Latin_1_Supp; \ 70 } else if (screen->vtXX_level < 2) { \ 71 charset = nrc_ASCII; \ 72 } \ 73 } 74 75static Boolean 76isSevenBit(DECNRCM_codes cs) 77{ 78 Boolean result = False; 79 80 switch (cs) { 81 case nrc_ISO_Greek_Supp: 82 case nrc_ISO_Hebrew_Supp: 83 case nrc_ISO_Latin_1_Supp: 84 case nrc_ISO_Latin_2_Supp: 85 case nrc_ISO_Latin_5_Supp: 86 case nrc_ISO_Latin_Cyrillic: 87 case nrc_DEC_UPSS: 88 break; 89 /* VT100 character sets */ 90 case nrc_ASCII: 91 case nrc_British: 92 case nrc_DEC_Alt_Chars: 93 case nrc_DEC_Spec_Graphic: 94 /* VT220 character sets */ 95 case nrc_DEC_Alt_Graphics: 96 case nrc_DEC_Supp: 97 /* VT320 character sets */ 98 case nrc_DEC_Supp_Graphic: 99 case nrc_DEC_Technical: 100 /* NRCS character sets (VT320 to VT520) */ 101 case nrc_British_Latin_1: 102 case nrc_Dutch: 103 case nrc_Finnish2: 104 case nrc_Finnish: 105 case nrc_French2: 106 case nrc_French: 107 case nrc_French_Canadian2: 108 case nrc_French_Canadian: 109 case nrc_German: 110 case nrc_Greek: 111 case nrc_Hebrew: 112 case nrc_Italian: 113 case nrc_Norwegian_Danish2: 114 case nrc_Norwegian_Danish3: 115 case nrc_Norwegian_Danish: 116 case nrc_Portugese: 117 case nrc_Russian: 118 case nrc_SCS_NRCS: 119 case nrc_Spanish: 120 case nrc_Swedish2: 121 case nrc_Swedish: 122 case nrc_Swiss: 123 case nrc_Turkish: 124 /* other DEC character sets */ 125 case nrc_DEC_Cyrillic: 126 case nrc_DEC_Greek_Supp: 127 case nrc_DEC_Hebrew_Supp: 128 case nrc_DEC_Turkish_Supp: 129 result = True; 130 break; 131 case nrc_Unknown: 132 break; 133 } 134 return result; 135} 136 137/* 138 * Translate an input keysym to the corresponding NRC keysym. 139 */ 140unsigned 141xtermCharSetIn(XtermWidget xw, unsigned code, DECNRCM_codes charset) 142{ 143 TScreen *screen = TScreenOf(xw); 144#define MAP(to, from) case from: code = to; break; 145 146#if OPT_WIDE_CHARS 147#define UNI(to, from) case from: if (screen->utf8_nrc_mode) code = to; break; 148#else 149#define UNI(to, from) case from: break; 150#endif 151 152#define XXX(to, from) /* no defined mapping to 0..255 */ 153 154 TRACE(("CHARSET-IN GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 155 visibleScsCode(screen->gsets[screen->curgl]), screen->curgl, 156 visibleScsCode(screen->gsets[screen->curgr]), screen->curgr, 157 screen->curss, 158 visibleUChar(code))); 159 160 HandleUPSS(charset); 161 162 switch (charset) { 163 case nrc_British: /* United Kingdom set (or Latin 1) */ 164 if (code == XK_sterling) 165 code = 0x23; 166 code &= 0x7f; 167 break; 168 169 case nrc_DEC_Alt_Chars: 170 case nrc_DEC_Alt_Graphics: 171 case nrc_ASCII: 172 break; 173 174 case nrc_DEC_Spec_Graphic: 175 break; 176 177 case nrc_DEC_Supp: 178 map_DEC_Supp_Graphic(code, code &= 0x7f); 179 break; 180 181 case nrc_DEC_Supp_Graphic: 182 map_DEC_Supp_Graphic(code, code |= 0x80); 183 break; 184 185 case nrc_DEC_Technical: 186 map_DEC_Technical(code); 187 break; 188 189 case nrc_Dutch: 190 map_NRCS_Dutch(code); 191 break; 192 193 case nrc_Finnish: 194 case nrc_Finnish2: 195 map_NRCS_Finnish(code); 196 break; 197 198 case nrc_French: 199 case nrc_French2: 200 map_NRCS_French(code); 201 break; 202 203 case nrc_French_Canadian: 204 map_NRCS_French_Canadian(code); 205 break; 206 207 case nrc_German: 208 map_NRCS_German(code); 209 break; 210 211 case nrc_Greek: 212 map_NRCS_Greek(code); /* FIXME - ELOT? */ 213 break; 214 215 case nrc_DEC_Greek_Supp: 216 map_DEC_Greek_Supp(code); 217 break; 218 219 case nrc_ISO_Greek_Supp: 220 map_ISO_Greek_Supp(code); 221 break; 222 223 case nrc_DEC_Hebrew_Supp: 224 map_DEC_Hebrew_Supp(code); 225 break; 226 227 case nrc_Hebrew: 228 map_NRCS_Hebrew(code); 229 break; 230 231 case nrc_ISO_Hebrew_Supp: 232 map_ISO_Hebrew(code); 233 break; 234 235 case nrc_Italian: 236 map_NRCS_Italian(code); 237 break; 238 239 case nrc_ISO_Latin_2_Supp: 240 map_ISO_Latin_2(code); 241 break; 242 243 case nrc_ISO_Latin_5_Supp: 244 map_ISO_Latin_5(code); 245 break; 246 247 case nrc_ISO_Latin_Cyrillic: 248 map_ISO_Latin_Cyrillic(code); 249 break; 250 251 case nrc_Norwegian_Danish: 252 case nrc_Norwegian_Danish2: 253 case nrc_Norwegian_Danish3: 254 map_NRCS_Norwegian_Danish(code); 255 break; 256 257 case nrc_Portugese: 258 map_NRCS_Portuguese(code); 259 break; 260 261 case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 262 /* FIXME */ 263 break; 264 265 case nrc_Spanish: 266 map_NRCS_Spanish(code); 267 break; 268 269 case nrc_Swedish2: 270 case nrc_Swedish: 271 map_NRCS_Swedish(code); 272 break; 273 274 case nrc_Swiss: 275 map_NRCS_Swiss(code); 276 break; 277 278 case nrc_Turkish: 279 map_NRCS_Turkish(code); 280 break; 281 282 case nrc_DEC_Turkish_Supp: 283 map_DEC_Turkish_Supp(code); 284 break; 285 286 case nrc_DEC_Cyrillic: 287 map_DEC_Cyrillic(code); 288 break; 289 290 case nrc_ISO_Latin_1_Supp: 291 case nrc_British_Latin_1: 292 case nrc_Russian: 293 case nrc_French_Canadian2: 294 case nrc_Unknown: 295 case nrc_DEC_UPSS: 296 default: /* any character sets we don't recognize */ 297 break; 298 } 299 code &= 0x7f; /* NRC in any case is 7-bit */ 300 TRACE(("->\t%s\n", 301 visibleUChar(code))); 302 return code; 303#undef MAP 304#undef UNI 305#undef XXX 306} 307 308/* 309 * Translate a string to the display form. This assumes the font has the 310 * DEC graphic characters in cells 0-31, and otherwise is ISO-8859-1. 311 */ 312Cardinal 313xtermCharSetOut(XtermWidget xw, Cardinal length, DECNRCM_codes leftset) 314{ 315 IChar *buf = xw->work.write_text; 316 IChar *ptr = buf + length; 317 IChar *s; 318 TScreen *screen = TScreenOf(xw); 319 Cardinal count = 0; 320 DECNRCM_codes rightset = screen->gsets[(int) (screen->curgr)]; 321#if OPT_DEC_RECTOPS 322 int sums = 0; 323#endif 324 325#define MAP(from, to) case from: chr = to; break; 326 327#if OPT_WIDE_CHARS 328#define UNI(from, to) case from: if (screen->utf8_nrc_mode) chr = to; break; 329#define XXX(from, to) UNI(from, to) 330#else 331#define UNI(old, new) case new: chr = old; break; 332#define XXX(from, to) /* nothing */ 333#endif 334 335 TRACE(("CHARSET-OUT GL=%s(G%d) GR=%s(G%d) SS%d\n\t%s\n", 336 visibleScsCode(leftset), screen->curgl, 337 visibleScsCode(rightset), screen->curgr, 338 screen->curss, 339 visibleIChars(buf, (size_t) length))); 340 341 assert(length != 0); 342#if OPT_DEC_RECTOPS 343 if (length != 0 && length > xw->work.sizeof_sums) { 344 xw->work.sizeof_sums += length + 80; 345 xw->work.buffer_sums = realloc(xw->work.buffer_sums, 346 xw->work.sizeof_sums); 347 xw->work.buffer_sets = realloc(xw->work.buffer_sets, 348 xw->work.sizeof_sums); 349 } 350 xw->work.write_sums = xw->work.buffer_sums; 351#endif 352 353 for (s = buf; s < ptr; ++s) { 354 int eight = CharOf(E2A(*s)); 355 int seven = eight & 0x7f; 356 DECNRCM_codes cs = (eight >= 128) ? rightset : leftset; 357 int chr = eight; 358 359 HandleUPSS(cs); 360 361#if OPT_DEC_RECTOPS 362 if (xw->work.buffer_sums != NULL && xw->work.buffer_sets != NULL) { 363 xw->work.buffer_sums[sums] = (Char) ((eight < 32 || eight > 255) 364 ? ANSI_ESC 365 : eight); 366 xw->work.buffer_sets[sums] = cs; 367 ++sums; 368 } 369#endif 370 count++; 371#if OPT_WIDE_CHARS 372 /* 373 * This is only partly right - prevent inadvertent remapping of 374 * the replacement character and other non-8bit codes into bogus 375 * 8bit codes. 376 */ 377 if (screen->utf8_mode || screen->utf8_nrc_mode) { 378 if (*s > 255) 379 continue; 380 } 381#endif 382 if (*s < 32) 383 continue; 384 385 switch (cs) { 386 case nrc_DEC_UPSS: 387 break; 388 389 case nrc_ISO_Latin_1_Supp: 390 case nrc_British_Latin_1: 391 case nrc_British: /* United Kingdom set (or Latin 1) */ 392 if ((xw->flags & NATIONAL) 393 || (screen->vtXX_level <= 1)) { 394 if ((xw->flags & NATIONAL)) { 395 chr = seven; 396 } 397 if (chr == 0x23) { 398 chr = XTERM_POUND; 399#if OPT_WIDE_CHARS 400 if (screen->utf8_nrc_mode) { 401 chr = 0xa3; 402 } 403#endif 404 } 405 } 406 break; 407 408 case nrc_DEC_Alt_Chars: 409 case nrc_DEC_Alt_Graphics: 410 case nrc_ASCII: 411 break; 412 413 case nrc_DEC_Spec_Graphic: 414 if (seven > 0x5f && seven <= 0x7e) { 415#if OPT_WIDE_CHARS 416 if (screen->utf8_mode || screen->utf8_nrc_mode) 417 chr = (int) dec2ucs(screen, (unsigned) (seven - 0x5f)); 418 else 419#endif 420 chr = seven - 0x5f; 421 } else if (chr == 0x5f) { 422 chr = 0; 423 } else { 424 chr = seven; 425 } 426 break; 427 428 case nrc_DEC_Supp: 429 case nrc_DEC_Supp_Graphic: 430 map_DEC_Supp_Graphic(chr = seven, chr = eight); 431 break; 432 433 case nrc_DEC_Technical: 434 map_DEC_Technical(chr = seven); 435 break; 436 437 case nrc_Dutch: 438 map_NRCS_Dutch(chr = seven); 439 break; 440 441 case nrc_Finnish: 442 case nrc_Finnish2: 443 map_NRCS_Finnish(chr = seven); 444 break; 445 446 case nrc_French: 447 case nrc_French2: 448 map_NRCS_French(chr = seven); 449 break; 450 451 case nrc_French_Canadian: 452 case nrc_French_Canadian2: 453 map_NRCS_French_Canadian(chr = seven); 454 break; 455 456 case nrc_German: 457 map_NRCS_German(chr = seven); 458 break; 459 460 case nrc_Greek: 461 map_NRCS_Greek(chr = seven); /* FIXME - ELOT? */ 462 break; 463 464 case nrc_DEC_Greek_Supp: 465 map_DEC_Greek_Supp(chr = seven); 466 break; 467 468 case nrc_ISO_Greek_Supp: 469 map_ISO_Greek_Supp(chr = seven); 470 break; 471 472 case nrc_DEC_Hebrew_Supp: 473 map_DEC_Hebrew_Supp(chr = seven); 474 break; 475 476 case nrc_Hebrew: 477 map_NRCS_Hebrew(chr = seven); 478 break; 479 480 case nrc_ISO_Hebrew_Supp: 481 map_ISO_Hebrew(chr = seven); 482 break; 483 484 case nrc_Italian: 485 map_NRCS_Italian(chr = seven); 486 break; 487 488 case nrc_ISO_Latin_2_Supp: 489 map_ISO_Latin_2(chr = seven); 490 break; 491 492 case nrc_ISO_Latin_5_Supp: 493 map_ISO_Latin_5(chr = seven); 494 break; 495 496 case nrc_ISO_Latin_Cyrillic: 497 map_ISO_Latin_Cyrillic(chr = seven); 498 break; 499 500 case nrc_Norwegian_Danish: 501 case nrc_Norwegian_Danish2: 502 case nrc_Norwegian_Danish3: 503 map_NRCS_Norwegian_Danish(chr = seven); 504 break; 505 506 case nrc_Portugese: 507 map_NRCS_Portuguese(chr = seven); 508 break; 509 510 case nrc_SCS_NRCS: /* vt5xx - Serbo/Croatian */ 511 /* FIXME */ 512 break; 513 514 case nrc_Spanish: 515 map_NRCS_Spanish(chr = seven); 516 break; 517 518 case nrc_Swedish2: 519 case nrc_Swedish: 520 map_NRCS_Swedish(chr = seven); 521 break; 522 523 case nrc_Swiss: 524 map_NRCS_Swiss(chr = seven); 525 break; 526 527 case nrc_Turkish: 528 map_NRCS_Turkish(chr = seven); 529 break; 530 531 case nrc_DEC_Turkish_Supp: 532 map_DEC_Turkish_Supp(chr = seven); 533 break; 534 535 case nrc_DEC_Cyrillic: 536 map_DEC_Cyrillic(chr = seven); 537 break; 538 539 case nrc_Russian: 540 case nrc_Unknown: 541 default: /* any character sets we don't recognize */ 542 break; 543 } 544 /* 545 * The state machine already treated DEL as a nonprinting and 546 * nonspacing character. If we have DEL now, remove it. 547 */ 548 if (chr == ANSI_DEL && isSevenBit(cs)) { 549 IChar *s1; 550 --ptr; 551 for (s1 = s; s1 < ptr; ++s1) { 552 s1[0] = s1[1]; 553 } 554 --count; 555#if OPT_DEC_RECTOPS 556 --sums; 557#endif 558 } else { 559 if (eight >= 128 && chr < 128 && chr > 32) 560 chr |= 128; 561 *s = (IChar) A2E(chr); 562 } 563 } 564 TRACE(("%d\t%s\n", 565 count, 566 visibleIChars(buf, (size_t) length))); 567 return count; 568#undef MAP 569#undef UNI 570#undef XXX 571} 572 573#if OPT_DEC_RECTOPS 574/* 575 * Given a mapped character, e.g., a Unicode value returned by xtermCharSetIn, 576 * match it against the current GL/GR selection and return the corresponding 577 * DEC internal character-set code for DECRQCRA. 578 * 579 * A hardware terminal presumably stores the original and mapped characters, 580 * as well as the character set which was selected at that time Doing that 581 * in xterm adds a couple of bytes to every cell. 582 */ 583int 584xtermCharSetDec(XtermWidget xw, IChar chr, DECNRCM_codes cs) 585{ 586#define MAP(from, to) case from: result = to; break; 587 588#define DFTMAP() result = (actual | 0x80) 589#define DFT_94(chr) result = ((actual) & 0x7f) 590#define DFT_96(chr) result = ((actual) | 0x80) 591 592#if OPT_WIDE_CHARS 593#define UNI(from, to) case from: if (screen->utf8_nrc_mode) result = to; break; 594#define XXX(from, to) UNI(from, to) 595#else 596#define UNI(old, new) case new: result = old; break; 597#define XXX(from, to) /* nothing */ 598#endif 599 600 int result; 601 602 if (chr < 0x20 603#if OPT_WIDE_CHARS 604 || chr > 0xff 605#endif 606 ) { 607 result = ANSI_ESC; 608 } else { 609 Boolean isSeven = isSevenBit(cs); 610 TScreen *screen = TScreenOf(xw); 611 612 result = -1; 613 614 HandleUPSS(cs); 615 616 if (chr == 0xa0 && isSeven) { 617 result = ANSI_ESC; 618 } else if (chr == ANSI_SPA && isSeven) { 619 result = ANSI_SPA; 620 } else if ((chr == ANSI_DEL || chr == 0xff) && isSeven) { 621 result = 0; 622 } else { 623 int actual = (int) chr; 624 chr &= 0x7f; 625 626 switch (cs) { 627 case nrc_DEC_Alt_Chars: 628 case nrc_DEC_Alt_Graphics: 629 case nrc_ASCII: 630 result = (int) chr; 631 break; 632 633 case nrc_British: 634 if (chr >= 0xa0 && chr < 0xff) { 635 if (chr == 0x23) 636 chr = 0xA3; 637 result = (int) chr; 638 } 639 break; 640 641 case nrc_DEC_Cyrillic: 642 unmap_DEC_Cyrillic(chr, DFT_94(chr)); 643 break; 644 645 case nrc_DEC_Spec_Graphic: 646 unmap_DEC_Spec_Graphic(chr, DFT_94(chr)); 647 break; 648 649 case nrc_DEC_Supp: 650 /* FALLTHRU */ 651 case nrc_DEC_Supp_Graphic: 652 unmap_DEC_Supp_Graphic(chr, DFTMAP()); 653 break; 654 655 case nrc_DEC_Technical: 656 unmap_DEC_Technical(chr, DFTMAP()); 657 break; 658 659 case nrc_Dutch: 660 unmap_NRCS_Dutch(chr, DFT_94(chr)); 661 break; 662 663 case nrc_Finnish: 664 case nrc_Finnish2: 665 unmap_NRCS_Finnish(chr, DFT_94(chr)); 666 break; 667 668 case nrc_French: 669 case nrc_French2: 670 unmap_NRCS_French(chr, DFT_94(chr)); 671 break; 672 673 case nrc_French_Canadian: 674 case nrc_French_Canadian2: 675 unmap_NRCS_French_Canadian(chr, DFT_94(chr)); 676 break; 677 678 case nrc_German: 679 unmap_NRCS_German(chr, DFT_94(chr)); 680 break; 681 682 case nrc_Greek: 683 unmap_NRCS_Greek(chr, DFT_94(chr)); 684 break; 685 686 case nrc_DEC_Greek_Supp: 687 unmap_DEC_Greek_Supp(chr, DFTMAP()); 688 break; 689 690 case nrc_ISO_Greek_Supp: 691 unmap_ISO_Greek_Supp(chr, DFTMAP()); 692 break; 693 694 case nrc_DEC_Hebrew_Supp: 695 unmap_DEC_Hebrew_Supp(chr, DFTMAP()); 696 break; 697 698 case nrc_Hebrew: 699 unmap_NRCS_Hebrew(chr, DFT_94(chr)); 700 break; 701 702 case nrc_ISO_Hebrew_Supp: 703 unmap_ISO_Hebrew(chr, DFTMAP()); 704 break; 705 706 case nrc_Italian: 707 unmap_NRCS_Italian(chr, DFT_94(chr)); 708 break; 709 710 case nrc_ISO_Latin_1_Supp: 711 unmap_ISO_Latin_1(chr, DFTMAP()); 712 break; 713 714 case nrc_ISO_Latin_2_Supp: 715 unmap_ISO_Latin_2(chr, DFTMAP()); 716 break; 717 718 case nrc_ISO_Latin_5_Supp: 719 unmap_ISO_Latin_5(chr, DFTMAP()); 720 break; 721 722 case nrc_ISO_Latin_Cyrillic: 723 unmap_ISO_Latin_Cyrillic(chr, DFTMAP()); 724 break; 725 726 case nrc_Norwegian_Danish: 727 case nrc_Norwegian_Danish2: 728 case nrc_Norwegian_Danish3: 729 unmap_NRCS_Norwegian_Danish(chr, DFT_94(chr)); 730 break; 731 732 case nrc_Portugese: 733 unmap_NRCS_Portuguese(chr, DFT_94(chr)); 734 break; 735 736 case nrc_Spanish: 737 unmap_NRCS_Spanish(chr, DFT_94(chr)); 738 break; 739 740 case nrc_Swedish: 741 case nrc_Swedish2: 742 unmap_NRCS_Swedish(chr, DFT_94(chr)); 743 break; 744 745 case nrc_Swiss: 746 unmap_NRCS_Swiss(chr, DFT_94(chr)); 747 break; 748 749 case nrc_DEC_Turkish_Supp: 750 unmap_DEC_Turkish_Supp(chr, DFTMAP()); 751 break; 752 753 case nrc_Turkish: 754 unmap_NRCS_Turkish(chr, DFT_94(chr)); 755 break; 756 757 case nrc_British_Latin_1: 758 case nrc_SCS_NRCS: 759 case nrc_Russian: 760 case nrc_Unknown: 761 case nrc_DEC_UPSS: 762 default: /* anything we cannot unmap */ 763 break; 764 } 765 if (result < 0) { 766 if (isSeven) { 767 DFT_94(chr); 768 } else { 769 DFT_96(chr); 770 } 771 } 772 } 773 } 774 return result; 775#undef MAP 776#undef UNI 777#undef XXX 778} 779#endif /* OPT_DEC_RECTOPS */ 780