Created
December 28, 2014 13:19
-
-
Save Tucos/6afb844041ac2a823bdb to your computer and use it in GitHub Desktop.
0001-Perform-proper-reordering-and-shaping-of-glyphs.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 9fdb5a85b250cc0bb80deb9f2783a16c9dcc7777 Mon Sep 17 00:00:00 2001 | |
From: Bas Pape <baspape@gmail.com> | |
Date: Sun, 28 Dec 2014 13:30:43 +0100 | |
Subject: [PATCH] Perform proper reordering and shaping of glyphs | |
All RTL languages require reordering of the characters before drawing | |
them, and various scripts require positional shaping (e.g. Arabic and | |
Mongolian) as well. FriBidi [1] implements the Unicode Bidirectional | |
Algorithm (UAX#9, [2]) and has a simple API (a single function call) to | |
do both reordering and reshaping. | |
The fribidi_log2vis function is marked as deprecated, but is unlikely to | |
be removed and is just a convenient function for one-line paragraphs [3]. | |
[1] http://fribidi.org/ | |
[2] http://www.unicode.org/reports/tr9/ | |
[3] http://lists.freedesktop.org/archives/fribidi/2008-January/000515.html | |
--- | |
configure.ac.in | 15 ++++++++++++ | |
src/conky.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- | |
2 files changed, 87 insertions(+), 2 deletions(-) | |
diff --git a/configure.ac.in b/configure.ac.in | |
index 313c92e..12a0bcf 100644 | |
--- a/configure.ac.in | |
+++ b/configure.ac.in | |
@@ -668,6 +668,19 @@ if test x$want_xft = "xyes"; then | |
fi | |
dnl | |
+dnl fribidi | |
+dnl | |
+AC_ARG_ENABLE([fribidi], | |
+ AC_HELP_STRING([--disable-fribidi], [Disable if you do not want to use FriBidi, used for reordering Unicode strings @<:default=yes@:>@]), | |
+ [want_fribidi="$enableval"], [want_fribidi=yes]) | |
+if test x"$want_fribidi" = "xyes"; then | |
+ PKG_CHECK_MODULES([fribidi], [fribidi]) | |
+ conky_CFLAGS="$conky_CFLAGS $fribidi_CFLAGS" | |
+ conky_LIBS="$conky_LIBS $fribidi_LIBS" | |
+ AC_DEFINE(HAVE_FRIBIDI, 1, [Define for FriBidi support]) | |
+fi | |
+ | |
+dnl | |
dnl NVIDIA libXNVCtrl support | |
dnl | |
@@ -1008,6 +1021,7 @@ $PACKAGE $VERSION configured successfully: | |
XDamage support: $want_xdamage | |
XDBE support: $want_double_buffer | |
Xft support: $want_xft | |
+ FriBidi support: $want_fribidi | |
ARGB support $want_argb | |
* Music detection: | |
@@ -1043,4 +1057,5 @@ dnl OpenMP: $want_openmp | |
Cairo: $want_lua_cairo | |
Imlib2: $want_lua_imlib2 | |
+ | |
EOF | |
diff --git a/src/conky.c b/src/conky.c | |
index 0a10562..3cb934e 100644 | |
--- a/src/conky.c | |
+++ b/src/conky.c | |
@@ -73,6 +73,9 @@ | |
#ifdef HAVE_CURL | |
#include <curl/curl.h> | |
#endif | |
+#ifdef HAVE_FRIBIDI | |
+#include <fribidi.h> | |
+#endif | |
/* local headers */ | |
#include "core.h" | |
@@ -214,6 +217,9 @@ static void print_version(void) | |
# ifdef USE_ARGB | |
" * ARGB visual\n" | |
# endif /* USE_ARGB */ | |
+# ifdef HAVE_FRIBIDI | |
+ " * FriBidi\n" | |
+# endif /* HAVE_FRIBIDI */ | |
#endif /* X11 */ | |
"\n Music detection:\n" | |
#ifdef AUDACIOUS | |
@@ -2795,16 +2801,80 @@ static inline void set_foreground_color(long c) | |
return; | |
} | |
-static void draw_string(const char *s) | |
+#if HAVE_FRIBIDI | |
+static char *reorder_unicode_string(const char * const src) | |
+{ | |
+ // 1. Convert to wchar array, which can be treated as FriBidiChar array | |
+ size_t nchars; | |
+ if ((nchars = mbstowcs(NULL, src, 1)) == (size_t)-1) { | |
+ NORM_ERR("Invalid byte sequence"); | |
+ return NULL; | |
+ } | |
+ | |
+ FriBidiChar *bidichars = calloc(nchars + 1, sizeof(FriBidiChar)); | |
+ if (!bidichars || mbstowcs((wchar_t *)bidichars, src, nchars + 1) != nchars) { | |
+ NORM_ERR("Out of memory"); | |
+ goto freebidi; | |
+ } | |
+ | |
+ | |
+ // 2. Reorder the character array and do Arabic joining | |
+ FriBidiChar *reordered = calloc(nchars + 1, sizeof(FriBidiChar)); | |
+ if (!reordered) { | |
+ NORM_ERR("Out of memory"); | |
+ goto freebidi; | |
+ } | |
+ FriBidiParType pbase_dir = FRIBIDI_PAR_ON; | |
+ if (!fribidi_log2vis(bidichars, nchars, &pbase_dir, reordered, NULL, NULL, NULL)) { | |
+ NORM_ERR("Failed to reorder the line"); | |
+ goto freereordered; | |
+ } | |
+ | |
+ | |
+ // 3. Convert wchar array back to mb string | |
+ size_t len; | |
+ if ((len = wcstombs(NULL, (wchar_t *)reordered, 1)) == (size_t)-1) { | |
+ NORM_ERR("Invalid byte sequence after reordering"); | |
+ goto freereordered; | |
+ } | |
+ | |
+ char *ret = calloc(len + 1, 1); | |
+ if (!ret || wcstombs(ret, (wchar_t *)reordered, len + 1) != len) { | |
+ NORM_ERR("Out of memory"); | |
+ goto freeret; | |
+ } | |
+ | |
+ free(reordered); | |
+ free(bidichars); | |
+ | |
+ return ret; | |
+ | |
+freeret: | |
+ free(ret); | |
+freereordered: | |
+ free(reordered); | |
+freebidi: | |
+ free(bidichars); | |
+ return NULL; | |
+} | |
+#endif | |
+ | |
+static void draw_string(const char *s1) | |
{ | |
int i, i2, pos, width_of_s; | |
int max = 0; | |
int added; | |
- if (s[0] == '\0') { | |
+ if (s1[0] == '\0') { | |
return; | |
} | |
+ const char *s = NULL; | |
+#if HAVE_FRIBIDI | |
+ if (utf8_mode) s = reorder_unicode_string(s1); | |
+#endif | |
+ if (!s) s = s1; | |
+ | |
width_of_s = get_string_width(s); | |
if ((output_methods & TO_STDOUT) && draw_mode == FG) { | |
printf("%s\n", s); | |
-- | |
1.8.5.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment