office-gobmx/harfbuzz/harfbuzz-0.9.16-winxp.patch.1
Fridrich Štrba 20b5cdbdfd Make harfbuzz Windows XP compatible
In a case we use harfbuzz on Windows once, it is using in the
uniscribe backend some OpenType shaping that is available only
in Vista and later. So call this functions over function pointers
if available and if not, fallback to the itemizing/shaping/placing
that is available in Windows XP uniscribe.

Change-Id: I5b1a22d812d57194d1147effa87033cdf6af78d3
2013-05-10 09:34:44 +02:00

137 lines
4.2 KiB
Groff

--- harfbuzz-0.9.16/src/hb-uniscribe.cc 2013-04-19 03:36:12.000000000 +0200
+++ harfbuzz-0.9.16/src/hb-uniscribe.cc 2013-05-08 17:13:37.874217344 +0200
@@ -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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);