}
/*
+ * Function exported to front ends to allow them to identify
+ * bidi-active characters (in case, for example, the platform's
+ * text display function can't conveniently be prevented from doing
+ * its own bidi and so special treatment is required for characters
+ * that would cause the bidi algorithm to activate).
+ *
+ * This function is passed a single Unicode code point, and returns
+ * nonzero if the presence of this code point can possibly cause
+ * the bidi algorithm to do any reordering. Thus, any string
+ * composed entirely of characters for which is_rtl() returns zero
+ * should be safe to pass to a bidi-active platform display
+ * function without fear.
+ *
+ * (is_rtl() must therefore also return true for any character
+ * which would be affected by Arabic shaping, but this isn't
+ * important because all such characters are right-to-left so it
+ * would have flagged them anyway.)
+ */
+int is_rtl(int c)
+{
+ /*
+ * After careful reading of the Unicode bidi algorithm (URL as
+ * given at the top of this file) I believe that the only
+ * character classes which can possibly cause trouble are R,
+ * AL, RLE and RLO. I think that any string containing no
+ * character in any of those classes will be displayed
+ * uniformly left-to-right by the Unicode bidi algorithm.
+ */
+ const int mask = (1<<R) | (1<<AL) | (1<<RLE) | (1<<RLO);
+
+ return mask & (1 << (getType(c)));
+}
+
+/*
* The most significant 2 bits of each level are used to store
* Override status of each character
* This function sets the override bits of level according
}
/*
+ * The exact_textout() wrapper, unfortunately, destroys the useful
+ * Windows `font linking' behaviour: automatic handling of Unicode
+ * code points not supported in this font by falling back to a font
+ * which does contain them. Therefore, we adopt a multi-layered
+ * approach: for any potentially-bidi text, we use exact_textout(),
+ * and for everything else we use a simple ExtTextOut as we did
+ * before exact_textout() was introduced.
+ */
+static void general_textout(HDC hdc, int x, int y, CONST RECT *lprc,
+ unsigned short *lpString, UINT cbCount,
+ CONST INT *lpDx, int opaque)
+{
+ int i, j, xp, xn;
+ RECT newrc;
+
+#ifdef FIXME_REMOVE_BEFORE_CHECKIN
+int k;
+debug(("general_textout: %d,%d", x, y));
+for(k=0;k<cbCount;k++)debug((" U+%04X", lpString[k]));
+debug(("\n rect: [%d,%d %d,%d]", lprc->left, lprc->top, lprc->right, lprc->bottom));
+debug(("\n"));
+#endif
+
+ xp = xn = x;
+
+ for (i = 0; i < cbCount ;) {
+ int rtl = is_rtl(lpString[i]);
+
+ xn += lpDx[i];
+
+ for (j = i+1; j < cbCount; j++) {
+ if (rtl != is_rtl(lpString[j]))
+ break;
+ xn += lpDx[j];
+ }
+
+ /*
+ * Now [i,j) indicates a maximal substring of lpString
+ * which should be displayed using the same textout
+ * function.
+ */
+ if (rtl) {
+ newrc.left = lprc->left + xp - x;
+ newrc.right = lprc->left + xn - x;
+ newrc.top = lprc->top;
+ newrc.bottom = lprc->bottom;
+#ifdef FIXME_REMOVE_BEFORE_CHECKIN
+{
+int k;
+debug((" exact_textout: %d,%d", xp, y));
+for(k=0;k<j-i;k++)debug((" U+%04X", lpString[i+k]));
+debug(("\n rect: [%d,%d %d,%d]\n", newrc.left, newrc.top, newrc.right, newrc.bottom));
+}
+#endif
+ exact_textout(hdc, xp, y, &newrc, lpString+i, j-i, lpDx+i, opaque);
+ } else {
+#ifdef FIXME_REMOVE_BEFORE_CHECKIN
+{
+int k;
+debug((" ExtTextOut : %d,%d", xp, y));
+for(k=0;k<j-i;k++)debug((" U+%04X", lpString[i+k]));
+debug(("\n rect: [%d,%d %d,%d]\n", newrc.left, newrc.top, newrc.right, newrc.bottom));
+}
+#endif
+ newrc.left = lprc->left + xp - x;
+ newrc.right = lprc->left + xn - x;
+ newrc.top = lprc->top;
+ newrc.bottom = lprc->bottom;
+ ExtTextOutW(hdc, xp, y, ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
+ &newrc, lpString+i, j-i, lpDx+i);
+ }
+
+ i = j;
+ xp = xn;
+ }
+
+#ifdef FIXME_REMOVE_BEFORE_CHECKIN
+debug(("general_textout: done, xn=%d\n", xn));
+#endif
+ assert(xn - x == lprc->right - lprc->left);
+}
+
+/*
* 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
* if/when they are needed.
wbuf[i] = text[i];
/* 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, !(attr & TATTR_COMBINING));
-/* ExtTextOutW(hdc, x,
- y - font_height * (lattr == LATTR_BOT) + text_adjust,
- ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
- */
+ general_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
+ &line_box, wbuf, len, IpDx, !(attr & TATTR_COMBINING));
/* And the shadow bold hack. */
if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {