1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 09:27:59 +00:00

At last! After much delay, much faffing back and forth, and much

enhancement and fiddling, I have now massaged Arabeyes' first patch
into a form I'm happy to check in. Phew.

[originally from svn r4236]
This commit is contained in:
Simon Tatham 2004-05-22 10:36:50 +00:00
parent fdcdecace9
commit fb7dd5a255
12 changed files with 2531 additions and 15 deletions

11
Recipe
View File

@ -166,13 +166,16 @@ install-strip:
# names. A line beginning `+' is assumed to continue the previous
# line.
# Terminal emulator and its (platform-independent) dependencies.
TERMINAL = terminal wcwidth ldiscucs logging tree234 minibidi
+ config dialog
# GUI front end and terminal emulator (putty, puttytel).
GUITERM = window windlg winctrls terminal sizetip wcwidth unicode ldiscucs
+ logging printing winutils dialog config wincfg tree234
GUITERM = TERMINAL window windlg winctrls sizetip unicode printing
+ winutils wincfg
# Same thing on Unix.
UXTERM = pterm config uxcfg dialog gtkdlg gtkcols gtkpanel tree234
+ terminal wcwidth uxucs ldiscucs logging uxprint xkeysym
UXTERM = TERMINAL pterm uxcfg gtkdlg gtkcols gtkpanel uxucs uxprint xkeysym
# Non-SSH back ends (putty, puttytel, plink).
NONSSH = telnet raw rlogin ldisc

View File

@ -1037,6 +1037,12 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
ctrl_checkbox(s, "Disable remote-controlled character set configuration",
'r', HELPCTX(features_charset), dlg_stdcheckbox_handler,
I(offsetof(Config,no_remote_charset)));
ctrl_checkbox(s, "Disable Arabic text shaping",
'l', HELPCTX(no_help), dlg_stdcheckbox_handler,
I(offsetof(Config, arabicshaping)));
ctrl_checkbox(s, "Disable bidirectional text display",
'j', HELPCTX(no_help), dlg_stdcheckbox_handler,
I(offsetof(Config, bidi)));
/*
* The Window panel.

View File

@ -1,4 +1,4 @@
\versionid $Id: config.but,v 1.77 2004/04/24 20:05:03 jacob Exp $
\versionid $Id: config.but,v 1.78 2004/05/22 10:36:50 simon Exp $
\C{config} Configuring PuTTY
@ -822,6 +822,47 @@ If you find that accented characters are not showing up the way you
expect them to, particularly if you're running BitchX, you could try
disabling the remote character set configuration commands.
\S{config-features-shaping} Disabling Arabic text shaping
\cfg{winhelp-topic}{features.arabicshaping}
PuTTY supports shaping of Arabic text, which means that if your
server sends text written in the basic Unicode Arabic alphabet then
it will convert it to the correct display forms before printing it
on the screen.
If you are using full-screen software which was not expecting this
to happen (especially if you are not an Arabic speaker and you
unexpectedly find yourself dealing with Arabic text files in
applications which are not Arabic-aware), you might find that the
display becomes corrupted. By ticking this box, you can disable
Arabic text shaping so that PuTTY displays precisely the characters
it is told to display.
You may also find you need to disable bidirectional text display;
see \S{config-features-bidi}.
\S{config-features-bidi} Disabling bidirectional text display
\cfg{winhelp-topic}{features.bidi}
PuTTY supports bidirectional text display, which means that if your
server sends text written in a language which is usually displayed
from right to left (such as Arabic or Hebrew) then PuTTY will
automatically flip it round so that it is displayed in the right
direction on the screen.
If you are using full-screen software which was not expecting this
to happen (especially if you are not an Arabic speaker and you
unexpectedly find yourself dealing with Arabic text files in
applications which are not Arabic-aware), you might find that the
display becomes corrupted. By ticking this box, you can disable
bidirectional text display, so that PuTTY displays text from left to
right in all situations.
You may also find you need to disable Arabic text shaping;
see \S{config-features-arabicshaping}.
\H{config-window} The Window panel
The Window configuration panel allows you to control aspects of the

31
ldisc.c
View File

@ -32,13 +32,20 @@ static int plen(Ldisc ldisc, unsigned char c)
return 1;
else if (c < 128)
return 2; /* ^x for some x */
else if (in_utf(ldisc->term) && c >= 0xC0)
return 1; /* UTF-8 introducer character
* (FIXME: combining / wide chars) */
else if (in_utf(ldisc->term) && c >= 0x80 && c < 0xC0)
return 0; /* UTF-8 followup character */
else
return 4; /* <XY> for hex XY */
return 4; /* <XY> hex representation */
}
static void pwrite(Ldisc ldisc, unsigned char c)
{
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term))) {
if ((c >= 32 && c <= 126) ||
(!in_utf(ldisc->term) && c >= 0xA0) ||
(in_utf(ldisc->term) && c >= 0x80)) {
c_write(ldisc, (char *)&c, 1);
} else if (c < 128) {
char cc[2];
@ -52,6 +59,14 @@ static void pwrite(Ldisc ldisc, unsigned char c)
}
}
static int char_start(Ldisc ldisc, unsigned char c)
{
if (in_utf(ldisc->term))
return (c < 0x80 || c >= 0xC0);
else
return 1;
}
static void bsb(Ldisc ldisc, int n)
{
while (n--)
@ -137,7 +152,9 @@ void ldisc_send(void *handle, char *buf, int len, int interactive)
c += KCTRL('@');
switch (ldisc->quotenext ? ' ' : c) {
/*
* ^h/^?: delete one char and output one BSB
* ^h/^?: delete, and output BSBs, to return to
* last character boundary (in UTF-8 mode this may
* be more than one byte)
* ^w: delete, and output BSBs, to return to last
* space/nonspace boundary
* ^u: delete, and output BSBs, to return to BOL
@ -153,9 +170,11 @@ void ldisc_send(void *handle, char *buf, int len, int interactive)
case KCTRL('H'):
case KCTRL('?'): /* backspace/delete */
if (ldisc->buflen > 0) {
if (ECHOING)
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
do {
if (ECHOING)
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
} while (!char_start(ldisc, ldisc->buf[ldisc->buflen]));
}
break;
case CTRL('W'): /* delete word */

1788
minibidi.c Normal file

File diff suppressed because it is too large Load Diff

456
minibidi.h Normal file
View File

@ -0,0 +1,456 @@
/************************************************************************
* $Id: minibidi.h,v 1.1 2004/05/22 10:36:50 simon Exp $
*
* ------------
* Description:
* ------------
* This is an implemention of Unicode's Bidirectional Algorithm
* (known as UAX #9).
*
* http://www.unicode.org/reports/tr9/
*
* Author: Ahmad Khalifa
*
* -----------------
* Revision Details: (Updated by Revision Control System)
* -----------------
* $Date: 2004/05/22 10:36:50 $
* $Author: simon $
* $Revision: 1.1 $
* $Source: /u1/simon/svn-migration/cvs/putty/minibidi.h,v $
*
* (www.arabeyes.org - under MIT license)
*
************************************************************************/
/*
* TODO:
* =====
* - work almost finished
* - Shaping Table to be expanded to include the whole range.
* - Ligature handling
*/
#include <stdlib.h> /* definition of wchar_t*/
#define LMASK 0x3F /* Embedding Level mask */
#define OMASK 0xC0 /* Override mask */
#define OISL 0x80 /* Override is L */
#define OISR 0x40 /* Override is R */
/* Shaping Helpers */
#define STYPE(xh) (((xh >= SHAPE_FIRST) && (xh <= SHAPE_LAST)) ? \
shapetypes[xh-SHAPE_FIRST].type : SU) /*))*/
#define SISOLATED(xh) (shapetypes[xh-SHAPE_FIRST].form_b)
#define SFINAL(xh) xh+1
#define SINITIAL(xh) xh+2
#define SMEDIAL(ch) ch+3
typedef struct bidi_char {
wchar_t origwc, wc;
unsigned short index;
} bidi_char;
/* function declarations */
void flipThisRun(bidi_char *from, unsigned char* level, int max, int count);
int findIndexOfRun(unsigned char* level , int start, int count, int tlevel);
unsigned char getType(wchar_t ch);
unsigned char setOverrideBits(unsigned char level, unsigned char override);
unsigned char getPreviousLevel(unsigned char* level, int from);
unsigned char leastGreaterOdd(unsigned char x);
unsigned char leastGreaterEven(unsigned char x);
unsigned char getRLE(wchar_t ch);
int do_shape(bidi_char *line, bidi_char *to, int count);
int do_bidi(bidi_char *line, int count);
void doMirror(wchar_t* ch);
/* character types */
enum
{
L,
LRE,
LRO,
R,
AL,
RLE,
RLO,
PDF,
EN,
ES,
ET,
AN,
CS,
NSM,
BN,
B,
S,
WS,
ON,
};
/* Shaping Types */
enum
{
SL, /* Left-Joining, doesnt exist in U+0600 - U+06FF */
SR, /* Right-Joining, ie has Isolated, Final */
SD, /* Dual-Joining, ie has Isolated, Final, Initial, Medial */
SU, /* Non-Joining */
SC /* Join-Causing, like U+0640 (TATWEEL) */
};
typedef struct{
char type;
wchar_t form_b;
} shape_node;
/* Kept near the actual table, for verification. */
#define SHAPE_FIRST 0x621
#define SHAPE_LAST 0x64A
const shape_node shapetypes[] = {
/* index, Typ, Iso, Ligature Index*/
/* 621 */ {SU, 0xFE80},
/* 622 */ {SR, 0xFE81},
/* 623 */ {SR, 0xFE83},
/* 624 */ {SR, 0xFE85},
/* 625 */ {SR, 0xFE87},
/* 626 */ {SD, 0xFE89},
/* 627 */ {SR, 0xFE8D},
/* 628 */ {SD, 0xFE8F},
/* 629 */ {SR, 0xFE93},
/* 62A */ {SD, 0xFE95},
/* 62B */ {SD, 0xFE99},
/* 62C */ {SD, 0xFE9D},
/* 62D */ {SD, 0xFEA1},
/* 62E */ {SD, 0xFEA5},
/* 62F */ {SR, 0xFEA9},
/* 630 */ {SR, 0xFEAB},
/* 631 */ {SR, 0xFEAD},
/* 632 */ {SR, 0xFEAF},
/* 633 */ {SD, 0xFEB1},
/* 634 */ {SD, 0xFEB5},
/* 635 */ {SD, 0xFEB9},
/* 636 */ {SD, 0xFEBD},
/* 637 */ {SD, 0xFEC1},
/* 638 */ {SD, 0xFEC5},
/* 639 */ {SD, 0xFEC9},
/* 63A */ {SD, 0xFECD},
/* 63B */ {SU, 0x0},
/* 63C */ {SU, 0x0},
/* 63D */ {SU, 0x0},
/* 63E */ {SU, 0x0},
/* 63F */ {SU, 0x0},
/* 640 */ {SC, 0x0},
/* 641 */ {SD, 0xFED1},
/* 642 */ {SD, 0xFED5},
/* 643 */ {SD, 0xFED9},
/* 644 */ {SD, 0xFEDD},
/* 645 */ {SD, 0xFEE1},
/* 646 */ {SD, 0xFEE5},
/* 647 */ {SD, 0xFEE9},
/* 648 */ {SR, 0xFEED},
/* 649 */ {SR, 0xFEEF}, /* SD */
/* 64A */ {SD, 0xFEF1},
};
/*
* This describes the data byte and its frequency
*/
typedef struct
{
unsigned char f;
unsigned char d;
}RLENode;
/* This is an array of RLENodes, which is the
* Compressed unicode types table
*/
const unsigned char RLE_table[] =
{
0x09, 0x10, 0x01, 0x0F, 0x01, 0x10, 0x01, 0x11,
0x01, 0x0F, 0x01, 0x0E, 0x0E, 0x0F, 0x03, 0x10,
0x01, 0x11, 0x01, 0x12, 0x02, 0x0A, 0x03, 0x12,
0x05, 0x0A, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x0C,
0x01, 0x09, 0x01, 0x08, 0x0A, 0x0C, 0x01, 0x12,
0x06, 0x00, 0x1A, 0x12, 0x06, 0x00, 0x1A, 0x12,
0x04, 0x0E, 0x06, 0x0F, 0x01, 0x0E, 0x1A, 0x0C,
0x01, 0x12, 0x01, 0x0A, 0x04, 0x12, 0x04, 0x00,
0x01, 0x12, 0x05, 0x0A, 0x02, 0x08, 0x02, 0x12,
0x01, 0x00, 0x01, 0x12, 0x03, 0x08, 0x01, 0x00,
0x01, 0x12, 0x05, 0x00, 0x17, 0x12, 0x01, 0x00,
0x1F, 0x12, 0x01, 0x00, 0xFF, 0x00, 0x2A, 0x12,
0x01, 0x00, 0x12, 0x12, 0x1C, 0x00, 0x5E, 0x12,
0x02, 0x00, 0x09, 0x12, 0x02, 0x00, 0x07, 0x12,
0x0E, 0x00, 0x02, 0x12, 0x0E, 0x00, 0x05, 0x12,
0x09, 0x00, 0x01, 0x12, 0x11, 0x0D, 0x50, 0x12,
0x10, 0x0D, 0x10, 0x12, 0x0A, 0x00, 0x01, 0x12,
0x0B, 0x00, 0x01, 0x12, 0x01, 0x00, 0x03, 0x12,
0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x14, 0x12,
0x01, 0x00, 0x2C, 0x12, 0x01, 0x00, 0x26, 0x12,
0x0A, 0x00, 0x83, 0x0D, 0x04, 0x12, 0x01, 0x0D,
0x02, 0x00, 0x45, 0x12, 0x01, 0x00, 0x26, 0x12,
0x02, 0x00, 0x02, 0x12, 0x06, 0x00, 0x10, 0x12,
0x21, 0x00, 0x26, 0x12, 0x02, 0x00, 0x07, 0x12,
0x01, 0x00, 0x27, 0x12, 0x01, 0x00, 0x01, 0x12,
0x07, 0x0D, 0x11, 0x12, 0x01, 0x0D, 0x17, 0x12,
0x01, 0x0D, 0x03, 0x03, 0x01, 0x0D, 0x01, 0x03,
0x01, 0x0D, 0x02, 0x03, 0x01, 0x0D, 0x01, 0x12,
0x0B, 0x03, 0x1B, 0x12, 0x05, 0x03, 0x05, 0x12,
0x17, 0x0C, 0x01, 0x12, 0x0E, 0x04, 0x01, 0x12,
0x03, 0x04, 0x01, 0x12, 0x01, 0x04, 0x1A, 0x12,
0x05, 0x04, 0x0B, 0x0D, 0x0B, 0x12, 0x0A, 0x0B,
0x0A, 0x0A, 0x01, 0x0B, 0x02, 0x04, 0x03, 0x0D,
0x01, 0x04, 0x65, 0x0D, 0x07, 0x04, 0x01, 0x0D,
0x07, 0x04, 0x02, 0x0D, 0x02, 0x12, 0x01, 0x0D,
0x04, 0x12, 0x02, 0x08, 0x0A, 0x04, 0x05, 0x12,
0x01, 0x04, 0x0E, 0x12, 0x01, 0x0E, 0x01, 0x04,
0x01, 0x0D, 0x01, 0x04, 0x1B, 0x12, 0x03, 0x0D,
0x1B, 0x12, 0x35, 0x04, 0x26, 0x0D, 0x0B, 0x04,
0x01, 0x12, 0xFF, 0x12, 0x50, 0x0D, 0x02, 0x00,
0x01, 0x12, 0x01, 0x00, 0x35, 0x12, 0x02, 0x0D,
0x01, 0x00, 0x04, 0x0D, 0x08, 0x00, 0x04, 0x0D,
0x01, 0x12, 0x02, 0x00, 0x01, 0x0D, 0x04, 0x12,
0x03, 0x00, 0x0A, 0x0D, 0x02, 0x00, 0x0D, 0x12,
0x10, 0x0D, 0x01, 0x00, 0x02, 0x12, 0x01, 0x00,
0x08, 0x12, 0x02, 0x00, 0x02, 0x12, 0x02, 0x00,
0x16, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
0x01, 0x12, 0x03, 0x00, 0x04, 0x12, 0x02, 0x0D,
0x01, 0x12, 0x01, 0x00, 0x03, 0x0D, 0x04, 0x12,
0x02, 0x00, 0x02, 0x12, 0x02, 0x00, 0x02, 0x0D,
0x01, 0x12, 0x09, 0x00, 0x01, 0x12, 0x04, 0x00,
0x02, 0x12, 0x01, 0x00, 0x03, 0x0D, 0x02, 0x12,
0x02, 0x00, 0x0C, 0x0A, 0x02, 0x00, 0x07, 0x12,
0x07, 0x0D, 0x01, 0x12, 0x02, 0x00, 0x06, 0x12,
0x04, 0x00, 0x02, 0x12, 0x02, 0x00, 0x16, 0x12,
0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x02, 0x12,
0x01, 0x00, 0x02, 0x12, 0x01, 0x00, 0x02, 0x12,
0x02, 0x0D, 0x01, 0x12, 0x01, 0x00, 0x03, 0x0D,
0x02, 0x12, 0x04, 0x0D, 0x02, 0x12, 0x02, 0x0D,
0x03, 0x12, 0x0B, 0x00, 0x04, 0x12, 0x01, 0x00,
0x01, 0x12, 0x07, 0x00, 0x0A, 0x0D, 0x02, 0x00,
0x03, 0x12, 0x0C, 0x0D, 0x02, 0x00, 0x01, 0x12,
0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x01, 0x12,
0x01, 0x00, 0x03, 0x12, 0x01, 0x00, 0x16, 0x12,
0x01, 0x00, 0x07, 0x12, 0x01, 0x00, 0x02, 0x12,
0x01, 0x00, 0x05, 0x12, 0x02, 0x0D, 0x01, 0x00,
0x04, 0x0D, 0x05, 0x12, 0x01, 0x0D, 0x02, 0x00,
0x01, 0x12, 0x01, 0x00, 0x02, 0x0D, 0x01, 0x12,
0x02, 0x00, 0x01, 0x12, 0x0F, 0x00, 0x01, 0x12,
0x05, 0x00, 0x0A, 0x12, 0x11, 0x0D, 0x01, 0x00,
0x02, 0x12, 0x01, 0x00, 0x08, 0x12, 0x02, 0x00,
0x02, 0x12, 0x02, 0x00, 0x16, 0x12, 0x01, 0x00,
0x07, 0x12, 0x01, 0x00, 0x02, 0x12, 0x02, 0x00,
0x04, 0x12, 0x02, 0x0D, 0x01, 0x00, 0x02, 0x0D,
0x01, 0x00, 0x01, 0x0D, 0x03, 0x12, 0x03, 0x00,
0x02, 0x12, 0x02, 0x00, 0x02, 0x0D, 0x01, 0x12,
0x08, 0x0D, 0x01, 0x00, 0x01, 0x12, 0x04, 0x00,
0x02, 0x12, 0x01, 0x00, 0x03, 0x12, 0x04, 0x00,
0x0B, 0x12, 0x11, 0x0D, 0x01, 0x00, 0x01, 0x12,
0x01, 0x00, 0x06, 0x12, 0x03, 0x00, 0x03, 0x12,
0x01, 0x00, 0x04, 0x12, 0x03, 0x00, 0x02, 0x12,
0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x02, 0x12,
0x03, 0x00, 0x02, 0x12, 0x03, 0x00, 0x03, 0x12,
0x03, 0x00, 0x08, 0x12, 0x01, 0x00, 0x03, 0x12,
0x04, 0x00, 0x02, 0x0D, 0x01, 0x00, 0x02, 0x12,
0x03, 0x00, 0x03, 0x12, 0x01, 0x00, 0x03, 0x0D,
0x01, 0x12, 0x09, 0x00, 0x01, 0x12, 0x0F, 0x00,
0x0C, 0x12, 0x0E, 0x00, 0x03, 0x12, 0x01, 0x00,
0x08, 0x12, 0x01, 0x00, 0x03, 0x12, 0x01, 0x00,
0x17, 0x12, 0x01, 0x00, 0x0A, 0x12, 0x01, 0x00,
0x05, 0x12, 0x04, 0x0D, 0x03, 0x00, 0x04, 0x12,
0x01, 0x0D, 0x03, 0x12, 0x01, 0x0D, 0x04, 0x12,
0x07, 0x0D, 0x02, 0x12, 0x09, 0x00, 0x02, 0x12,
0x04, 0x00, 0x0A, 0x12, 0x12, 0x00, 0x02, 0x12,
0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x03, 0x12,
0x01, 0x00, 0x17, 0x12, 0x01, 0x00, 0x0A, 0x12,
0x01, 0x00, 0x05, 0x12, 0x04, 0x00, 0x01, 0x0D,
0x01, 0x00, 0x05, 0x12, 0x01, 0x0D, 0x01, 0x00,
0x02, 0x12, 0x01, 0x00, 0x02, 0x0D, 0x02, 0x12,
0x07, 0x00, 0x02, 0x12, 0x07, 0x00, 0x01, 0x12,
0x01, 0x00, 0x02, 0x12, 0x04, 0x00, 0x0A, 0x12,
0x12, 0x00, 0x02, 0x12, 0x01, 0x00, 0x08, 0x12,
0x01, 0x00, 0x03, 0x12, 0x01, 0x00, 0x17, 0x12,
0x01, 0x00, 0x10, 0x12, 0x04, 0x00, 0x03, 0x0D,
0x03, 0x12, 0x02, 0x00, 0x03, 0x12, 0x01, 0x00,
0x03, 0x0D, 0x01, 0x12, 0x09, 0x00, 0x01, 0x12,
0x08, 0x00, 0x02, 0x12, 0x04, 0x00, 0x0A, 0x12,
0x12, 0x00, 0x02, 0x12, 0x01, 0x00, 0x12, 0x12,
0x03, 0x00, 0x18, 0x12, 0x01, 0x00, 0x09, 0x12,
0x01, 0x00, 0x01, 0x12, 0x02, 0x00, 0x07, 0x12,
0x03, 0x0D, 0x01, 0x12, 0x04, 0x00, 0x03, 0x0D,
0x03, 0x12, 0x01, 0x0D, 0x01, 0x12, 0x01, 0x00,
0x08, 0x12, 0x12, 0x00, 0x03, 0x12, 0x0C, 0x00,
0x30, 0x0D, 0x01, 0x00, 0x02, 0x0D, 0x07, 0x12,
0x04, 0x0A, 0x01, 0x00, 0x07, 0x0D, 0x08, 0x00,
0x0D, 0x12, 0x25, 0x00, 0x02, 0x12, 0x01, 0x00,
0x01, 0x12, 0x02, 0x00, 0x02, 0x12, 0x01, 0x00,
0x01, 0x12, 0x02, 0x00, 0x01, 0x12, 0x06, 0x00,
0x04, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
0x03, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x01, 0x12, 0x02, 0x00, 0x02, 0x12, 0x01, 0x00,
0x04, 0x0D, 0x01, 0x00, 0x02, 0x0D, 0x06, 0x12,
0x01, 0x0D, 0x02, 0x00, 0x01, 0x12, 0x02, 0x00,
0x05, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x0D,
0x06, 0x12, 0x02, 0x00, 0x0A, 0x12, 0x02, 0x00,
0x02, 0x12, 0x22, 0x00, 0x18, 0x0D, 0x02, 0x00,
0x1B, 0x0D, 0x01, 0x00, 0x01, 0x0D, 0x01, 0x00,
0x01, 0x0D, 0x01, 0x12, 0x04, 0x00, 0x0A, 0x12,
0x01, 0x00, 0x22, 0x12, 0x06, 0x0D, 0x0E, 0x00,
0x01, 0x0D, 0x05, 0x00, 0x01, 0x0D, 0x02, 0x00,
0x04, 0x12, 0x04, 0x0D, 0x08, 0x12, 0x01, 0x0D,
0x24, 0x12, 0x01, 0x00, 0x08, 0x0D, 0x01, 0x00,
0x06, 0x12, 0x02, 0x00, 0x01, 0x12, 0x30, 0x00,
0x22, 0x12, 0x01, 0x00, 0x05, 0x12, 0x01, 0x00,
0x02, 0x12, 0x01, 0x00, 0x01, 0x0D, 0x04, 0x00,
0x01, 0x0D, 0x01, 0x12, 0x03, 0x0D, 0x02, 0x00,
0x01, 0x0D, 0x01, 0x12, 0x06, 0x00, 0x18, 0x0D,
0x02, 0x12, 0x46, 0x00, 0x26, 0x12, 0x0A, 0x00,
0x29, 0x12, 0x02, 0x00, 0x01, 0x12, 0x04, 0x00,
0x5A, 0x12, 0x05, 0x00, 0x44, 0x12, 0x05, 0x00,
0x52, 0x12, 0x06, 0x00, 0x07, 0x12, 0x01, 0x00,
0x3F, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
0x01, 0x12, 0x01, 0x00, 0x04, 0x12, 0x02, 0x00,
0x27, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x04, 0x12, 0x02, 0x00, 0x1F, 0x12, 0x01, 0x00,
0x01, 0x12, 0x01, 0x00, 0x04, 0x12, 0x02, 0x00,
0x07, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
0x07, 0x12, 0x01, 0x00, 0x17, 0x12, 0x01, 0x00,
0x1F, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x04, 0x12, 0x02, 0x00, 0x07, 0x12, 0x01, 0x00,
0x27, 0x12, 0x01, 0x00, 0x13, 0x12, 0x06, 0x00,
0x1C, 0x12, 0x23, 0x00, 0x55, 0x12, 0x0C, 0x00,
0xFF, 0x00, 0xFF, 0x00, 0x78, 0x12, 0x09, 0x11,
0x01, 0x00, 0x1A, 0x12, 0x05, 0x00, 0x51, 0x12,
0x0F, 0x00, 0x0D, 0x12, 0x01, 0x00, 0x04, 0x0D,
0x03, 0x12, 0x0B, 0x00, 0x12, 0x0D, 0x03, 0x00,
0x02, 0x12, 0x09, 0x00, 0x12, 0x0D, 0x02, 0x12,
0x0C, 0x00, 0x0D, 0x12, 0x01, 0x00, 0x03, 0x12,
0x01, 0x0D, 0x02, 0x12, 0x0C, 0x00, 0x37, 0x0D,
0x07, 0x00, 0x08, 0x0D, 0x01, 0x00, 0x02, 0x0D,
0x0B, 0x00, 0x07, 0x0A, 0x01, 0x00, 0x01, 0x12,
0x03, 0x00, 0x0A, 0x12, 0x21, 0x0D, 0x03, 0x0E,
0x01, 0x12, 0x01, 0x00, 0x0A, 0x12, 0x06, 0x00,
0x58, 0x12, 0x08, 0x00, 0x29, 0x0D, 0x01, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0x5B, 0x00, 0x9C, 0x12, 0x04, 0x00,
0x5A, 0x12, 0x06, 0x00, 0x16, 0x12, 0x02, 0x00,
0x06, 0x12, 0x02, 0x00, 0x26, 0x12, 0x02, 0x00,
0x06, 0x12, 0x02, 0x00, 0x08, 0x12, 0x01, 0x00,
0x01, 0x12, 0x01, 0x00, 0x01, 0x12, 0x01, 0x00,
0x01, 0x12, 0x01, 0x00, 0x1F, 0x12, 0x02, 0x00,
0x35, 0x12, 0x01, 0x00, 0x07, 0x12, 0x01, 0x00,
0x01, 0x12, 0x03, 0x00, 0x03, 0x12, 0x01, 0x00,
0x07, 0x12, 0x03, 0x00, 0x04, 0x12, 0x02, 0x00,
0x06, 0x12, 0x04, 0x00, 0x0D, 0x12, 0x05, 0x00,
0x03, 0x12, 0x01, 0x00, 0x07, 0x12, 0x03, 0x11,
0x0B, 0x0E, 0x03, 0x00, 0x01, 0x03, 0x01, 0x12,
0x18, 0x11, 0x01, 0x0F, 0x01, 0x01, 0x01, 0x05,
0x01, 0x07, 0x01, 0x02, 0x01, 0x06, 0x01, 0x11,
0x01, 0x0A, 0x05, 0x12, 0x2A, 0x11, 0x01, 0x0E,
0x04, 0x12, 0x06, 0x0E, 0x06, 0x08, 0x01, 0x00,
0x01, 0x12, 0x02, 0x08, 0x06, 0x0A, 0x02, 0x12,
0x03, 0x00, 0x01, 0x08, 0x0A, 0x0A, 0x02, 0x12,
0x14, 0x0A, 0x12, 0x12, 0x1E, 0x0D, 0x1B, 0x12,
0x17, 0x00, 0x01, 0x12, 0x04, 0x00, 0x01, 0x12,
0x02, 0x00, 0x0A, 0x12, 0x01, 0x00, 0x01, 0x12,
0x03, 0x00, 0x05, 0x12, 0x06, 0x00, 0x01, 0x12,
0x01, 0x00, 0x01, 0x12, 0x01, 0x00, 0x01, 0x12,
0x01, 0x00, 0x04, 0x0A, 0x01, 0x00, 0x03, 0x12,
0x01, 0x00, 0x07, 0x12, 0x03, 0x00, 0x03, 0x12,
0x05, 0x00, 0x05, 0x12, 0x16, 0x00, 0x24, 0x12,
0x8E, 0x0A, 0x02, 0x12, 0xFF, 0x12, 0x23, 0x00,
0x45, 0x12, 0x1A, 0x00, 0x01, 0x12, 0xCA, 0x08,
0x3C, 0x00, 0x4E, 0x08, 0x01, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0x20, 0x11, 0x01, 0x12,
0x04, 0x00, 0x03, 0x12, 0x19, 0x00, 0x09, 0x0D,
0x06, 0x12, 0x01, 0x00, 0x05, 0x12, 0x02, 0x00,
0x05, 0x12, 0x04, 0x00, 0x56, 0x12, 0x02, 0x0D,
0x02, 0x12, 0x02, 0x00, 0x03, 0x12, 0x01, 0x00,
0x5A, 0x12, 0x01, 0x00, 0x04, 0x12, 0x05, 0x00,
0x28, 0x12, 0x04, 0x00, 0x5E, 0x12, 0x01, 0x00,
0x28, 0x12, 0x38, 0x00, 0x2D, 0x12, 0x03, 0x00,
0x24, 0x12, 0x1C, 0x00, 0x1C, 0x12, 0x03, 0x00,
0x32, 0x12, 0x0F, 0x00, 0x0C, 0x12, 0x04, 0x00,
0x2F, 0x12, 0x01, 0x00, 0x77, 0x12, 0x04, 0x00,
0x63, 0x12, 0x02, 0x00, 0x1F, 0x12, 0x01, 0x00,
0x01, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xCD, 0x00, 0x01, 0x12,
0x4A, 0x00, 0x01, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xF5, 0x00,
0x01, 0x12, 0x5A, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xFF, 0x00, 0xFF, 0x00, 0x91, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0x7A, 0x00, 0x01, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xCD, 0x00,
0x01, 0x12, 0x5C, 0x00, 0x01, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0x81, 0x00, 0x02, 0x12,
0x7E, 0x00, 0x02, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0x02, 0x00, 0x02, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12, 0xFF, 0x12,
0xFF, 0x12, 0x17, 0x00, 0xFF, 0x00, 0x30, 0x12,
0x02, 0x00, 0x3B, 0x12, 0x95, 0x00, 0x07, 0x12,
0x0C, 0x00, 0x05, 0x12, 0x05, 0x03, 0x01, 0x0D,
0x01, 0x03, 0x0A, 0x0A, 0x01, 0x03, 0x0D, 0x12,
0x01, 0x03, 0x05, 0x12, 0x01, 0x03, 0x01, 0x12,
0x01, 0x03, 0x02, 0x12, 0x01, 0x03, 0x02, 0x12,
0x01, 0x03, 0x0A, 0x04, 0x62, 0x12, 0x21, 0x04,
0xFF, 0x04, 0x6C, 0x12, 0x12, 0x04, 0x40, 0x12,
0x02, 0x04, 0x36, 0x12, 0x28, 0x04, 0x0D, 0x12,
0x03, 0x0D, 0x10, 0x12, 0x10, 0x0D, 0x04, 0x12,
0x2C, 0x0C, 0x01, 0x12, 0x01, 0x0C, 0x01, 0x12,
0x02, 0x0C, 0x01, 0x12, 0x09, 0x0A, 0x01, 0x12,
0x02, 0x0A, 0x02, 0x12, 0x05, 0x0A, 0x02, 0x12,
0x05, 0x04, 0x05, 0x12, 0x01, 0x04, 0x87, 0x12,
0x02, 0x0E, 0x01, 0x12, 0x03, 0x0A, 0x03, 0x12,
0x05, 0x0A, 0x01, 0x0C, 0x01, 0x0A, 0x01, 0x0C,
0x01, 0x09, 0x01, 0x08, 0x0A, 0x0C, 0x01, 0x12,
0x06, 0x00, 0x1A, 0x12, 0x06, 0x00, 0x1A, 0x12,
0x0B, 0x00, 0x59, 0x12, 0x03, 0x00, 0x06, 0x12,
0x02, 0x00, 0x06, 0x12, 0x02, 0x00, 0x06, 0x12,
0x02, 0x00, 0x03, 0x12, 0x03, 0x0A, 0x02, 0x12,
0x03, 0x0A, 0x02, 0x12, 0x09, 0x00, 0x0E, 0x00,
};

12
putty.h
View File

@ -428,6 +428,8 @@ struct config_tag {
int window_border;
char answerback[256];
char printer[128];
int arabicshaping;
int bidi;
/* Colour options */
int system_colour;
int try_palette;
@ -830,6 +832,16 @@ struct controlbox;
void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
int midsession, int protocol);
/*
* Exports from minibidi.c.
*/
typedef struct bidi_char {
wchar_t origwc, wc;
unsigned short index;
} bidi_char;
int do_bidi(bidi_char *line, int count);
int do_shape(bidi_char *line, bidi_char *to, int count);
/*
* X11 auth mechanisms we know about.
*/

View File

@ -274,6 +274,8 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "DECOriginMode", cfg->dec_om);
write_setting_i(sesskey, "AutoWrapMode", cfg->wrap_mode);
write_setting_i(sesskey, "LFImpliesCR", cfg->lfhascr);
write_setting_i(sesskey, "DisableArabicShaping", cfg->arabicshaping);
write_setting_i(sesskey, "DisableBidi", cfg->bidi);
write_setting_i(sesskey, "WinNameAlways", cfg->win_name_always);
write_setting_s(sesskey, "WinTitle", cfg->wintitle);
write_setting_i(sesskey, "TermWidth", cfg->width);
@ -283,6 +285,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "UseSystemColours", cfg->system_colour);
write_setting_i(sesskey, "TryPalette", cfg->try_palette);
write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour);
for (i = 0; i < 22; i++) {
char buf[20], buf2[30];
sprintf(buf, "Colour%d", i);
@ -531,6 +534,8 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppi(sesskey, "DECOriginMode", 0, &cfg->dec_om);
gppi(sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
gppi(sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
gppi(sesskey, "DisableArabicShaping", 0, &cfg->arabicshaping);
gppi(sesskey, "DisableBidi", 0, &cfg->bidi);
gppi(sesskey, "WinNameAlways", 1, &cfg->win_name_always);
gpps(sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
gppi(sesskey, "TermWidth", 80, &cfg->width);
@ -540,6 +545,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppi(sesskey, "UseSystemColours", 0, &cfg->system_colour);
gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);
for (i = 0; i < 22; i++) {
static const char *const defaults[] = {
"187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",

View File

@ -237,6 +237,15 @@ void term_update(Terminal *term)
term->seen_disp_event = 0;
need_sbar_update = TRUE;
}
/* Allocate temporary buffers for Arabic shaping and bidi. */
if (!term->cfg.arabicshaping || !term->cfg.bidi)
{
term->wcFrom = sresize(term->wcFrom, term->cols, bidi_char);
term->ltemp = sresize(term->ltemp, term->cols+1, unsigned long);
term->wcTo = sresize(term->wcTo, term->cols, bidi_char);
}
if (need_sbar_update)
update_sbar(term);
do_paint(term, ctx, TRUE);
@ -428,6 +437,12 @@ Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata,
term->resize_fn = NULL;
term->resize_ctx = NULL;
term->in_term_out = FALSE;
term->ltemp = NULL;
term->wcFrom = NULL;
term->wcTo = NULL;
term->bidi_cache_size = 0;
term->pre_bidi_cache = term->post_bidi_cache = NULL;
return term;
}
@ -436,6 +451,7 @@ void term_free(Terminal *term)
{
unsigned long *line;
struct beeptime *beep;
int i;
while ((line = delpos234(term->scrollback, 0)) != NULL)
sfree(line);
@ -457,6 +473,17 @@ void term_free(Terminal *term)
printer_finish_job(term->print_job);
bufchain_clear(&term->printer_buf);
sfree(term->paste_buffer);
sfree(term->ltemp);
sfree(term->wcFrom);
sfree(term->wcTo);
for (i = 0; i < term->bidi_cache_size; i++) {
sfree(term->pre_bidi_cache[i]);
sfree(term->post_bidi_cache[i]);
}
sfree(term->pre_bidi_cache);
sfree(term->post_bidi_cache);
sfree(term);
}
@ -3302,13 +3329,66 @@ static int linecmp(Terminal *term, unsigned long *a, unsigned long *b)
}
#endif
/*
* To prevent having to run the reasonably tricky bidi algorithm
* too many times, we maintain a cache of the last lineful of data
* fed to the algorithm on each line of the display.
*/
static int term_bidi_cache_hit(Terminal *term, int line,
unsigned long *lbefore, int width)
{
if (!term->pre_bidi_cache)
return FALSE; /* cache doesn't even exist yet! */
if (line >= term->bidi_cache_size)
return FALSE; /* cache doesn't have this many lines */
if (!term->pre_bidi_cache[line])
return FALSE; /* cache doesn't contain _this_ line */
if (!memcmp(term->pre_bidi_cache[line], lbefore,
width * sizeof(unsigned long)))
return TRUE; /* aha! the line matches the cache */
return FALSE; /* it didn't match. */
}
static void term_bidi_cache_store(Terminal *term, int line,
unsigned long *lbefore,
unsigned long *lafter, int width)
{
if (!term->pre_bidi_cache || term->bidi_cache_size <= line) {
int j = term->bidi_cache_size;
term->bidi_cache_size = line+1;
term->pre_bidi_cache = sresize(term->pre_bidi_cache,
term->bidi_cache_size,
unsigned long *);
term->post_bidi_cache = sresize(term->post_bidi_cache,
term->bidi_cache_size,
unsigned long *);
while (j < term->bidi_cache_size) {
term->pre_bidi_cache[j] = term->post_bidi_cache[j] = NULL;
j++;
}
}
sfree(term->pre_bidi_cache[line]);
sfree(term->post_bidi_cache[line]);
term->pre_bidi_cache[line] = snewn(width, unsigned long);
term->post_bidi_cache[line] = snewn(width, unsigned long);
memcpy(term->pre_bidi_cache[line], lbefore, width * sizeof(unsigned long));
memcpy(term->post_bidi_cache[line], lafter, width * sizeof(unsigned long));
}
/*
* Given a context, update the window. Out of paranoia, we don't
* allow WM_PAINT responses to do scrolling optimisations.
*/
static void do_paint(Terminal *term, Context ctx, int may_optimise)
{
int i, j, our_curs_y, our_curs_x;
int i, it, j, our_curs_y, our_curs_x;
unsigned long rv, cursor;
pos scrpos;
char ch[1024];
@ -3324,8 +3404,8 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
if (term->in_vbell) {
ticks = GETTICKCOUNT();
if (ticks - term->vbell_startpoint >= VBELL_TIMEOUT)
term->in_vbell = FALSE;
}
term->in_vbell = FALSE;
}
rv = (!term->rvideo ^ !term->in_vbell ? ATTR_REVERSE : 0);
@ -3411,6 +3491,67 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
term->disptext[idx + term->cols]);
term->disptext[idx + term->cols] = ldata[term->cols];
/* Do Arabic shaping and bidi. */
if(!term->cfg.bidi || !term->cfg.arabicshaping) {
if (!term_bidi_cache_hit(term, i, ldata, term->cols)) {
for(it=0; it<term->cols ; it++)
{
int uc = (ldata[it] & 0xFFFF);
switch (uc & CSET_MASK) {
case ATTR_LINEDRW:
if (!term->cfg.rawcnp) {
uc = term->ucsdata->unitab_xterm[uc & 0xFF];
break;
}
case ATTR_ASCII:
uc = term->ucsdata->unitab_line[uc & 0xFF];
break;
case ATTR_SCOACS:
uc = term->ucsdata->unitab_scoacs[uc&0xFF];
break;
}
switch (uc & CSET_MASK) {
case ATTR_ACP:
uc = term->ucsdata->unitab_font[uc & 0xFF];
break;
case ATTR_OEMCP:
uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
break;
}
term->wcFrom[it].origwc = term->wcFrom[it].wc = uc;
term->wcFrom[it].index = it;
}
if(!term->cfg.bidi)
do_bidi(term->wcFrom, term->cols);
/* this is saved iff done from inside the shaping */
if(!term->cfg.bidi && term->cfg.arabicshaping)
for(it=0; it<term->cols; it++)
term->wcTo[it] = term->wcFrom[it];
if(!term->cfg.arabicshaping)
do_shape(term->wcFrom, term->wcTo, term->cols);
for(it=0; it<term->cols ; it++)
{
term->ltemp[it] = ldata[term->wcTo[it].index];
if (term->wcTo[it].origwc != term->wcTo[it].wc)
term->ltemp[it] = ((term->ltemp[it] & 0xFFFF0000) |
term->wcTo[it].wc);
}
term_bidi_cache_store(term, i, ldata, term->ltemp, term->cols);
ldata = term->ltemp;
} else {
ldata = term->post_bidi_cache[i];
}
}
for (j = 0; j < term->cols; j++, idx++) {
unsigned long tattr, tchar;
unsigned long *d = ldata + j;

View File

@ -208,6 +208,14 @@ struct terminal_tag {
* through.
*/
int in_term_out;
/*
* These are buffers used by the bidi and Arabic shaping code.
*/
unsigned long *ltemp;
bidi_char *wcFrom, *wcTo;
unsigned long **pre_bidi_cache, **post_bidi_cache;
int bidi_cache_size;
};
#define in_utf(term) ((term)->utf || (term)->ucsdata->line_codepage==CP_UTF8)

View File

@ -1080,6 +1080,36 @@ static void init_palette(void)
defpal[i].rgbtGreen, defpal[i].rgbtBlue);
}
/*
* This is a wrapper to ExtTextOut() to force Windows to display
* the precise glyphs we give it. Otherwise it would do its own
* bidi and Arabic shaping, and we would end up uncertain which
* characters it had put where.
*/
static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
unsigned short *lpString, UINT cbCount,
CONST INT *lpDx)
{
GCP_RESULTSW gcpr;
char *buffer = snewn(cbCount*2+2, char);
char *classbuffer = snewn(cbCount, char);
memset(&gcpr, 0, sizeof(gcpr));
memset(buffer, 0, cbCount*2+2);
memset(classbuffer, GCPCLASS_NEUTRAL, cbCount);
gcpr.lStructSize = sizeof(gcpr);
gcpr.lpGlyphs = (void *)buffer;
gcpr.lpClass = classbuffer;
gcpr.nGlyphs = cbCount;
GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
FLI_MASK | GCP_CLASSIN);
ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
buffer, cbCount, lpDx);
}
/*
* Initialise all the fonts we will need initially. There may be as many as
* three or as few as one. The other (poentially) twentyone fonts are done
@ -2989,9 +3019,13 @@ void do_text(Context ctx, int x, int y, char *text, int len,
for (i = 0; i < len; i++)
wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
ExtTextOutW(hdc, x,
/* print Glyphs as they are, without Windows' Shaping*/
exact_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
&line_box, wbuf, len, IpDx);
/* ExtTextOutW(hdc, x,
y - font_height * (lattr == LATTR_BOT) + text_adjust,
ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
*/
/* And the shadow bold hack. */
if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {

View File

@ -29,6 +29,8 @@
#define WINHELP_CTX_features_qtitle "features.qtitle"
#define WINHELP_CTX_features_dbackspace "features.dbackspace"
#define WINHELP_CTX_features_charset "features.charset"
#define WINHELP_CTX_features_arabicshaping "features.arabicshaping"
#define WINHELP_CTX_features_bidi "features.bidi"
#define WINHELP_CTX_terminal_autowrap "terminal.autowrap"
#define WINHELP_CTX_terminal_decom "terminal.decom"
#define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr"