#ifndef _WIN32 #include #else #define WIN32_LEAN_AND_MEAN #include #endif #define FRIBIDI_SHIM_IMPLEMENTATION #include "fribidi.h" /* FriBiDi>=1.0.0 adds bracket_types param, ignore and call legacy function */ static FriBidiLevel fribidi_get_par_embedding_levels_ex_compat( const FriBidiCharType *bidi_types, const FriBidiBracketType *bracket_types, const FriBidiStrIndex len, FriBidiParType *pbase_dir, FriBidiLevel *embedding_levels) { return fribidi_get_par_embedding_levels( bidi_types, len, pbase_dir, embedding_levels); } /* FriBiDi>=1.0.0 gets bracket types here, ignore */ static void fribidi_get_bracket_types_compat( const FriBidiChar *str, const FriBidiStrIndex len, const FriBidiCharType *types, FriBidiBracketType *btypes) { /* no-op*/ } int load_fribidi(void) { int error = 0; const char **p_fribidi_version_info = 0; p_fribidi = 0; /* Microsoft needs a totally different system */ #ifndef _WIN32 #define LOAD_FUNCTION(func) \ func = (t_##func)dlsym(p_fribidi, #func); \ error = error || (func == 0); p_fribidi = dlopen("libfribidi.so", RTLD_LAZY); if (!p_fribidi) { p_fribidi = dlopen("libfribidi.so.0", RTLD_LAZY); } if (!p_fribidi) { p_fribidi = dlopen("libfribidi.dylib", RTLD_LAZY); } if (!p_fribidi) { p_fribidi = dlopen("/usr/local/lib/libfribidi.dylib", RTLD_LAZY); } #else #define LOAD_FUNCTION(func) \ func = (t_##func)GetProcAddress(p_fribidi, #func); \ error = error || (func == 0); p_fribidi = LoadLibrary("fribidi"); if (!p_fribidi) { p_fribidi = LoadLibrary("fribidi-0"); } /* MSYS2 */ if (!p_fribidi) { p_fribidi = LoadLibrary("libfribidi-0"); } #endif if (!p_fribidi) { return 1; } /* load FriBiDi>=1.0.0 functions first, use error to detect version */ LOAD_FUNCTION(fribidi_get_par_embedding_levels_ex); LOAD_FUNCTION(fribidi_get_bracket_types); if (error) { /* using FriBiDi<1.0.0, ignore new parameters */ error = 0; fribidi_get_par_embedding_levels_ex = &fribidi_get_par_embedding_levels_ex_compat; fribidi_get_bracket_types = &fribidi_get_bracket_types_compat; } LOAD_FUNCTION(fribidi_unicode_to_charset); LOAD_FUNCTION(fribidi_charset_to_unicode); LOAD_FUNCTION(fribidi_get_bidi_types); LOAD_FUNCTION(fribidi_get_par_embedding_levels); #ifndef _WIN32 p_fribidi_version_info = (const char**)dlsym(p_fribidi, "fribidi_version_info"); if (error || (p_fribidi_version_info == 0) || (*p_fribidi_version_info == 0)) { dlclose(p_fribidi); p_fribidi = 0; return 2; } #else p_fribidi_version_info = (const char**)GetProcAddress(p_fribidi, "fribidi_version_info"); if (error || (p_fribidi_version_info == 0) || (*p_fribidi_version_info == 0)) { FreeLibrary(p_fribidi); p_fribidi = 0; return 2; } #endif fribidi_version_info = *p_fribidi_version_info; return 0; }