From 653fc8d97fc3e7c8f45008155bf8d253d5e8b383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fridrich=20=C5=A0trba?= Date: Thu, 9 May 2013 23:28:51 +0200 Subject: [PATCH] Fix Uniscribe backend on Windows XP Call the OpenType functions (that are Vista+ only) over function pointers and if they are not present in usp10.dll, fall back to the ScriptItemize, ScriptShape and ScriptPlace that are present on Windows XP too. --- src/hb-uniscribe.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 2f01c28..b4fafb3 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -44,6 +44,10 @@ #endif +typedef HRESULT WINAPI (*SIOT)(const WCHAR*,int,int,const SCRIPT_CONTROL*,const SCRIPT_STATE*,SCRIPT_ITEM*,OPENTYPE_TAG*,int*); +typedef HRESULT WINAPI (*SSOT)(HDC,SCRIPT_CACHE*,SCRIPT_ANALYSIS*,OPENTYPE_TAG,OPENTYPE_TAG,int*,TEXTRANGE_PROPERTIES**,int,const WCHAR*,int,int,WORD*,SCRIPT_CHARPROP*,WORD*,SCRIPT_GLYPHPROP*,int*); +typedef HRESULT WINAPI (*SPOT)(HDC,SCRIPT_CACHE*,SCRIPT_ANALYSIS*,OPENTYPE_TAG,OPENTYPE_TAG,int*,TEXTRANGE_PROPERTIES**,int,const WCHAR*,const WORD*,const SCRIPT_CHARPROP*,int,const WORD*,const SCRIPT_GLYPHPROP*,int,int*,GOFFSET*,ABC*); + /* DWORD GetFontData( __in HDC hdc, @@ -240,6 +244,11 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, hb_face_t *face = font->face; hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + SIOT siot = NULL; + SSOT ssot = NULL; + SPOT spot = NULL; + HMODULE hinstLib = GetModuleHandle("usp10.dll"); + #define FAIL(...) \ HB_STMT_START { \ @@ -249,6 +258,15 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, HRESULT hr; + if (hinstLib) + { + siot = (SIOT)GetProcAddress(hinstLib, "ScriptItemizeOpenType"); + + ssot = (SSOT)GetProcAddress(hinstLib, "ScriptShapeOpenType"); + + spot = (SPOT)GetProcAddress(hinstLib, "ScriptPlaceOpenType"); + } + retry: unsigned int scratch_size; @@ -291,6 +309,7 @@ retry: ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); + ALLOCATE_ARRAY (SCRIPT_VISATTR, vis_attr, glyphs_size); ALLOCATE_ARRAY (int, advances, glyphs_size); ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); @@ -312,7 +331,8 @@ retry: bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; bidi_state.fOverrideDirection = 1; - hr = ScriptItemizeOpenType (wchars, + if (siot && ssot && spot) { + hr = siot (wchars, chars_len, MAX_ITEMS, &bidi_control, @@ -320,6 +340,16 @@ retry: items, script_tags, &item_count); + } + else { + hr = ScriptItemize(wchars, + chars_len, + MAX_ITEMS, + &bidi_control, + &bidi_state, + items, + &item_count); + } if (unlikely (FAILED (hr))) FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr); @@ -344,7 +374,8 @@ retry: unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; retry_shape: - hr = ScriptShapeOpenType (font_data->hdc, + if (siot && ssot && spot) { + hr = ssot (font_data->hdc, &font_data->script_cache, &items[i].a, script_tags[i], @@ -361,6 +392,20 @@ retry: glyphs + glyphs_offset, glyph_props + glyphs_offset, (int *) &glyphs_len); + } + else { + hr = ScriptShape (font_data->hdc, + &font_data->script_cache, + wchars + chars_offset, + item_chars_len, + glyphs_size - glyphs_offset, + &items[i].a, + /* out */ + glyphs + glyphs_offset, + log_clusters + chars_offset, + vis_attr + glyphs_offset, + (int *) &glyphs_len); + } if (unlikely (items[i].a.fNoGlyphIndex)) FAIL ("ScriptShapeOpenType() set fNoGlyphIndex"); @@ -386,7 +431,8 @@ retry: for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++) log_clusters[j] += glyphs_offset; - hr = ScriptPlaceOpenType (font_data->hdc, + if (siot && ssot && spot) { + hr = spot (font_data->hdc, &font_data->script_cache, &items[i].a, script_tags[i], @@ -405,6 +451,19 @@ retry: advances + glyphs_offset, offsets + glyphs_offset, NULL); + } + else { + hr = ScriptPlace (font_data->hdc, + &font_data->script_cache, + glyphs + glyphs_offset, + glyphs_len, + vis_attr + glyphs_offset, + &items[i].a, + /* out */ + advances + glyphs_offset, + offsets + glyphs_offset, + NULL); + } if (unlikely (FAILED (hr))) FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr); -- 1.8.2.2