+#include <stdlib.h> /* definition of wchar_t*/
+
+#include "misc.h"
+
+#define LMASK 0x3F /* Embedding Level mask */
+#define OMASK 0xC0 /* Override mask */
+#define OISL 0x80 /* Override is L */
+#define OISR 0x40 /* Override is R */
+
+/* For standalone compilation in a testing mode.
+ * Still depends on the PuTTY headers for snewn and sfree, but can avoid
+ * _linking_ with any other PuTTY code. */
+#ifdef TEST_GETTYPE
+#define safemalloc malloc
+#define safefree free
+#endif
+
+/* 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)
+
+#define leastGreaterOdd(x) ( ((x)+1) | 1 )
+#define leastGreaterEven(x) ( ((x)+2) &~ 1 )
+
+typedef struct bidi_char {
+ unsigned int 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(int ch);
+unsigned char setOverrideBits(unsigned char level, unsigned char override);
+int getPreviousLevel(unsigned char* level, int from);
+int do_shape(bidi_char *line, bidi_char *to, int count);
+int do_bidi(bidi_char *line, int count);
+void doMirror(unsigned int *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 (SHAPE_FIRST + lenof(shapetypes) - 1)
+
+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},
+ /* 64B */ {SU, 0x0},
+ /* 64C */ {SU, 0x0},
+ /* 64D */ {SU, 0x0},
+ /* 64E */ {SU, 0x0},
+ /* 64F */ {SU, 0x0},
+ /* 650 */ {SU, 0x0},
+ /* 651 */ {SU, 0x0},
+ /* 652 */ {SU, 0x0},
+ /* 653 */ {SU, 0x0},
+ /* 654 */ {SU, 0x0},
+ /* 655 */ {SU, 0x0},
+ /* 656 */ {SU, 0x0},
+ /* 657 */ {SU, 0x0},
+ /* 658 */ {SU, 0x0},
+ /* 659 */ {SU, 0x0},
+ /* 65A */ {SU, 0x0},
+ /* 65B */ {SU, 0x0},
+ /* 65C */ {SU, 0x0},
+ /* 65D */ {SU, 0x0},
+ /* 65E */ {SU, 0x0},
+ /* 65F */ {SU, 0x0},
+ /* 660 */ {SU, 0x0},
+ /* 661 */ {SU, 0x0},
+ /* 662 */ {SU, 0x0},
+ /* 663 */ {SU, 0x0},
+ /* 664 */ {SU, 0x0},
+ /* 665 */ {SU, 0x0},
+ /* 666 */ {SU, 0x0},
+ /* 667 */ {SU, 0x0},
+ /* 668 */ {SU, 0x0},
+ /* 669 */ {SU, 0x0},
+ /* 66A */ {SU, 0x0},
+ /* 66B */ {SU, 0x0},
+ /* 66C */ {SU, 0x0},
+ /* 66D */ {SU, 0x0},
+ /* 66E */ {SU, 0x0},
+ /* 66F */ {SU, 0x0},
+ /* 670 */ {SU, 0x0},
+ /* 671 */ {SR, 0xFB50},
+ /* 672 */ {SU, 0x0},
+ /* 673 */ {SU, 0x0},
+ /* 674 */ {SU, 0x0},
+ /* 675 */ {SU, 0x0},
+ /* 676 */ {SU, 0x0},
+ /* 677 */ {SU, 0x0},
+ /* 678 */ {SU, 0x0},
+ /* 679 */ {SD, 0xFB66},
+ /* 67A */ {SD, 0xFB5E},
+ /* 67B */ {SD, 0xFB52},
+ /* 67C */ {SU, 0x0},
+ /* 67D */ {SU, 0x0},
+ /* 67E */ {SD, 0xFB56},
+ /* 67F */ {SD, 0xFB62},
+ /* 680 */ {SD, 0xFB5A},
+ /* 681 */ {SU, 0x0},
+ /* 682 */ {SU, 0x0},
+ /* 683 */ {SD, 0xFB76},
+ /* 684 */ {SD, 0xFB72},
+ /* 685 */ {SU, 0x0},
+ /* 686 */ {SD, 0xFB7A},
+ /* 687 */ {SD, 0xFB7E},
+ /* 688 */ {SR, 0xFB88},
+ /* 689 */ {SU, 0x0},
+ /* 68A */ {SU, 0x0},
+ /* 68B */ {SU, 0x0},
+ /* 68C */ {SR, 0xFB84},
+ /* 68D */ {SR, 0xFB82},
+ /* 68E */ {SR, 0xFB86},
+ /* 68F */ {SU, 0x0},
+ /* 690 */ {SU, 0x0},
+ /* 691 */ {SR, 0xFB8C},
+ /* 692 */ {SU, 0x0},
+ /* 693 */ {SU, 0x0},
+ /* 694 */ {SU, 0x0},
+ /* 695 */ {SU, 0x0},
+ /* 696 */ {SU, 0x0},
+ /* 697 */ {SU, 0x0},
+ /* 698 */ {SR, 0xFB8A},
+ /* 699 */ {SU, 0x0},
+ /* 69A */ {SU, 0x0},
+ /* 69B */ {SU, 0x0},
+ /* 69C */ {SU, 0x0},
+ /* 69D */ {SU, 0x0},
+ /* 69E */ {SU, 0x0},
+ /* 69F */ {SU, 0x0},
+ /* 6A0 */ {SU, 0x0},
+ /* 6A1 */ {SU, 0x0},
+ /* 6A2 */ {SU, 0x0},
+ /* 6A3 */ {SU, 0x0},
+ /* 6A4 */ {SD, 0xFB6A},
+ /* 6A5 */ {SU, 0x0},
+ /* 6A6 */ {SD, 0xFB6E},
+ /* 6A7 */ {SU, 0x0},
+ /* 6A8 */ {SU, 0x0},
+ /* 6A9 */ {SD, 0xFB8E},
+ /* 6AA */ {SU, 0x0},
+ /* 6AB */ {SU, 0x0},
+ /* 6AC */ {SU, 0x0},
+ /* 6AD */ {SD, 0xFBD3},
+ /* 6AE */ {SU, 0x0},
+ /* 6AF */ {SD, 0xFB92},
+ /* 6B0 */ {SU, 0x0},
+ /* 6B1 */ {SD, 0xFB9A},
+ /* 6B2 */ {SU, 0x0},
+ /* 6B3 */ {SD, 0xFB96},
+ /* 6B4 */ {SU, 0x0},
+ /* 6B5 */ {SU, 0x0},
+ /* 6B6 */ {SU, 0x0},
+ /* 6B7 */ {SU, 0x0},
+ /* 6B8 */ {SU, 0x0},
+ /* 6B9 */ {SU, 0x0},
+ /* 6BA */ {SR, 0xFB9E},
+ /* 6BB */ {SD, 0xFBA0},
+ /* 6BC */ {SU, 0x0},
+ /* 6BD */ {SU, 0x0},
+ /* 6BE */ {SD, 0xFBAA},
+ /* 6BF */ {SU, 0x0},
+ /* 6C0 */ {SR, 0xFBA4},
+ /* 6C1 */ {SD, 0xFBA6},
+ /* 6C2 */ {SU, 0x0},
+ /* 6C3 */ {SU, 0x0},
+ /* 6C4 */ {SU, 0x0},
+ /* 6C5 */ {SR, 0xFBE0},
+ /* 6C6 */ {SR, 0xFBD9},
+ /* 6C7 */ {SR, 0xFBD7},
+ /* 6C8 */ {SR, 0xFBDB},
+ /* 6C9 */ {SR, 0xFBE2},
+ /* 6CA */ {SU, 0x0},
+ /* 6CB */ {SR, 0xFBDE},
+ /* 6CC */ {SD, 0xFBFC},
+ /* 6CD */ {SU, 0x0},
+ /* 6CE */ {SU, 0x0},
+ /* 6CF */ {SU, 0x0},
+ /* 6D0 */ {SU, 0x0},
+ /* 6D1 */ {SU, 0x0},
+ /* 6D2 */ {SR, 0xFBAE},
+};