+ /* Non BMP characters must be handled by the uniscribe shaping
+ engine as GDI functions (except blindly displaying lines of
+ unicode text) and the promising looking ScriptGetCMap do not
+ convert surrogate pairs to glyph indexes correctly. */
+ {
+ items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1);
+ if (SUCCEEDED (ScriptItemize (ch, len, 2, NULL, NULL, items, &nitems)))
+ {
+ HRESULT result;
+ /* Some Indic characters result in more than 1 glyph. */
+ WORD glyphs[1], clusters[1];
+ SCRIPT_VISATTR attrs[1];
+ int nglyphs;
+
+ result = ScriptShape (context, &(uniscribe_font->cache),
+ ch, len, 1, &(items[0].a),
+ glyphs, clusters, attrs, &nglyphs);
+
+ if (result == E_PENDING)
+ {
+ /* Use selected frame until API is updated to pass
+ the frame. */
+ f = XFRAME (selected_frame);
+ context = get_frame_dc (f);
+ old_font = SelectObject (context, FONT_HANDLE(font));
+ result = ScriptShape (context, &(uniscribe_font->cache),
+ ch, len, 2, &(items[0].a),
+ glyphs, clusters, attrs, &nglyphs);
+ }
+
+ if (SUCCEEDED (result) && nglyphs == 1)
+ {
+ code = glyphs[0];
+ }
+ else if (SUCCEEDED (result) || result == E_OUTOFMEMORY)
+ {
+ /* This character produces zero or more than one glyph
+ when shaped. But we still need the return from here
+ to be valid for the shaping engine to be invoked
+ later. */
+ result = ScriptGetCMap (context, &(uniscribe_font->cache),
+ ch, len, 0, glyphs);
+ if (SUCCEEDED (result))
+ return glyphs[0];
+ else
+ return 0; /* notdef - enough in some cases to get the script
+ engine working, but not others... */
+ }
+ }
+ }
+ if (context)
+ {
+ SelectObject (context, old_font);
+ release_frame_dc (f, context);
+ }