RTL support in menus

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22945 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 9487053..ff29397 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -40,6 +40,7 @@
 #include "sound.h"
 #include "misc.h"
 #include "viewport.h"
+#include "language.h"
 
 #define ICON_PADDING 1
 
@@ -61,6 +62,9 @@
         | | | items      |   I - icons
         | | |            |
         ------------------
+
+        Note: This image is flipped horizontally when the language is a
+        right-to-left one (Hebrew, Arabic)
 */
 static bool draw_title(struct screen *display, struct gui_synclist *list)
 {
@@ -77,10 +81,17 @@
         struct viewport title_icon = title_text[screen];
         title_icon.width = get_icon_width(screen)
                           + ICON_PADDING*2;
-        title_icon.x += ICON_PADDING;
-
+        if (lang_is_rtl())
+        {
+            title_icon.x = title_text[screen].width - ICON_PADDING -
+                get_icon_width(screen);
+        }
+        else
+        {
+            title_icon.x = ICON_PADDING;
+            title_text[screen].x += title_icon.width;
+        }
         title_text[screen].width -= title_icon.width;
-        title_text[screen].x += title_icon.width;
 
         display->set_viewport(&title_icon);
         screen_put_icon(display, 0, 0, list->title_icon);
@@ -108,7 +119,7 @@
 #ifdef HAVE_LCD_COLOR
     unsigned char cur_line = 0;
 #endif
-    int item_offset;
+    int item_offset, is_rtl = lang_is_rtl();
     bool show_title;
     line_height = font_get(parent->font)->height;
     display->set_viewport(parent);
@@ -132,12 +143,12 @@
         vp = list_text[screen];
         vp.width = SCROLLBAR_WIDTH;
         list_text[screen].width -= SCROLLBAR_WIDTH;
-        if(global_settings.scrollbar == SCROLLBAR_LEFT)
+        if (global_settings.scrollbar == SCROLLBAR_SHOW)
             list_text[screen].x += SCROLLBAR_WIDTH;
         vp.height = line_height *
                     viewport_get_nb_lines(&list_text[screen]);
         vp.x = parent->x;
-        if(global_settings.scrollbar == SCROLLBAR_RIGHT)
+        if (global_settings.scrollbar == SCROLLBAR_SHOW_OPPOSITE)
             vp.x += list_text[screen].width;
         display->set_viewport(&vp);
         gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1,
@@ -149,7 +160,7 @@
     else if (show_title)
     {
         /* shift everything right a bit... */
-        if(global_settings.scrollbar == SCROLLBAR_LEFT)
+        if (global_settings.scrollbar == SCROLLBAR_SHOW)
         {
             list_text[screen].width -= SCROLLBAR_WIDTH;
             list_text[screen].x += SCROLLBAR_WIDTH;
@@ -167,8 +178,10 @@
         list_icons.width = icon_width * icon_count;
         list_text[screen].width -= 
                 list_icons.width + ICON_PADDING;
-        list_text[screen].x += 
-                list_icons.width + ICON_PADDING;
+        if (is_rtl)
+            list_icons.x += list_text[screen].width;
+        else
+            list_text[screen].x += list_icons.width + ICON_PADDING;
     }
     
     for (i=start; i<end && i<list->nb_items; i++)
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index 53cfd87..a473c82 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -29,6 +29,7 @@
 #include "settings.h"
 #include "bmp.h"
 #include "filetypes.h"
+#include "language.h"
 
 #include "bitmaps/default_icons.h"
 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
@@ -170,6 +171,8 @@
 #endif
         draw_func   = display->bitmap_part;
 
+    if (lang_is_rtl())
+        xpos = display->getwidth() - xpos - width;
     draw_func(data, 0, height * icon, stride, xpos, ypos, width, height);
 }
 
diff --git a/apps/lang/arabic.lang b/apps/lang/arabic.lang
index c06af35..73a98fe 100644
--- a/apps/lang/arabic.lang
+++ b/apps/lang/arabic.lang
@@ -17,6 +17,9 @@
 # Arabic language file, translated by:
 # - Mohamed Tarek
 # - Raafat Akkad
+<options>
+  rtl: 1
+</options>
 <phrase>
   id: LANG_EQUALIZER_HARDWARE_BANDWIDTH_NARROW
   desc: deprecated
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 8be7380..d34b2e9 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -13075,3 +13075,54 @@
     swcodec: "Release Time"
   </voice>
 </phrase>
+<phrase>
+  id: LANG_HIDE
+  desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
+  user: core
+  <source>
+    *: none
+    lcd_bitmap: "Hide"
+  </source>
+  <dest>
+    *: none
+    lcd_bitmap: "Hide"
+  </dest>
+  <voice>
+    *: none
+    lcd_bitmap: "Hide"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_SHOW
+  desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
+  user: core
+  <source>
+    *: none
+    lcd_bitmap: "Show"
+  </source>
+  <dest>
+    *: none
+    lcd_bitmap: "Show"
+  </dest>
+  <voice>
+    *: none
+    lcd_bitmap: "Show"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_SHOW_OPPOSITE
+  desc: in Settings -> General -> Display -> Status-/Scrollbar -> Scrollbar
+  user: core
+  <source>
+    *: none
+    lcd_bitmap: "Show Opposite"
+  </source>
+  <dest>
+    *: none
+    lcd_bitmap: "Show Opposite"
+  </dest>
+  <voice>
+    *: none
+    lcd_bitmap: "Show Opposite"
+  </voice>
+</phrase>
diff --git a/apps/lang/hebrew.lang b/apps/lang/hebrew.lang
index 76deb4d..449bbfe 100644
--- a/apps/lang/hebrew.lang
+++ b/apps/lang/hebrew.lang
@@ -20,6 +20,10 @@
 # - Rani Hod
 # - Tomer Shalev
 # - Sasha Khamkov
+
+<options>
+  rtl: 1
+</options>
 <phrase>
   id: LANG_SET_BOOL_YES
   desc: bool true representation
diff --git a/apps/language.c b/apps/language.c
index bba1359..0c6245f 100644
--- a/apps/language.c
+++ b/apps/language.c
@@ -34,9 +34,10 @@
 /* These defines must match the initial bytes in the binary lang file */
 /* See tools/genlang (TODO: Use common include for both) */
 #define LANGUAGE_COOKIE   0x1a
-#define LANGUAGE_VERSION  0x04
+#define LANGUAGE_VERSION  0x05
+#define LANGUAGE_FLAG_RTL 0x01
 
-#define HEADER_SIZE 3
+#define HEADER_SIZE 4
 
 static unsigned char language_buffer[MAX_LANGUAGE_SIZE];
 
@@ -51,6 +52,13 @@
     }
 }
 
+static unsigned char lang_options = 0;
+
+int lang_is_rtl(void)
+{
+    return (lang_options & LANGUAGE_FLAG_RTL) != 0;
+}
+
 int lang_load(const char *filename)
 {
     int fsize;
@@ -98,6 +106,7 @@
         retcode = 3;
     }
     close(fd);
+    lang_options = (retcode ? 0 : lang_header[3]);
     return retcode;
 }
 
diff --git a/apps/language.h b/apps/language.h
index 06769a3..c2a1b70 100644
--- a/apps/language.h
+++ b/apps/language.h
@@ -30,4 +30,6 @@
 /* get the ID of an english string so it can be localised */
 int lang_english_to_id(const char* english);
 
+/* returns whether the loaded language is a right-to-left language */
+int lang_is_rtl(void);
 #endif
diff --git a/apps/settings.h b/apps/settings.h
index b208ee5..b64fe37 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -158,7 +158,7 @@
 enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL };
 
 /* scrollbar visibility/position */
-enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT };
+enum { SCROLLBAR_HIDE = 0, SCROLLBAR_SHOW, SCROLLBAR_SHOW_OPPOSITE };
 
 /* Alarm settings */
 #ifdef HAVE_RTC_ALARM
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 62a9351..d76c2de 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -641,8 +641,9 @@
                   ID2P(LANG_STATUSBAR_BOTTOM)),
 #endif
     CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, scrollbar,
-                  LANG_SCROLL_BAR, SCROLLBAR_LEFT, "scrollbar","off,left,right",
-                  NULL, 3, ID2P(LANG_OFF), ID2P(LANG_LEFT), ID2P(LANG_RIGHT)),
+                  LANG_SCROLL_BAR, SCROLLBAR_SHOW,
+                  "scrollbar","hide,show,show_opposite", NULL, 3,
+                  ID2P(LANG_HIDE), ID2P(LANG_SHOW), ID2P(LANG_SHOW_OPPOSITE)),
     INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
                 "scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,
                 NULL, NULL, NULL),
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index c1efd90..8d3b88f 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -27,6 +27,7 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
+#include "language.h"
 
 #ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */
 #define LCDFN(fn) lcd_ ## fn
@@ -170,11 +171,16 @@
                               int style, int offset)
 {
     int xpos, ypos, w, h;
+    unsigned long chars_in_str;
     LCDFN(scroll_stop_line)(current_vp, y);
     if(!str || !str[0])
         return;
+
+    chars_in_str = utf8length((char *)str);
     LCDFN(getstringsize)(str, &w, &h);
-    xpos = x * w / utf8length((char *)str);
+    xpos = x * w / chars_in_str;
+    if (lang_is_rtl())
+        xpos = current_vp->width - w - xpos;
     ypos = y * h;
     LCDFN(putsxyofs_style)(xpos, ypos, str, style, w, h, offset);
 }
diff --git a/tools/genlang b/tools/genlang
index d191a82..44dfcc6 100755
--- a/tools/genlang
+++ b/tools/genlang
@@ -13,7 +13,8 @@
 # See apps/language.c (TODO: Use common include for both)
 # Cookie and binary version for the binary lang file
 my $LANGUAGE_COOKIE   = 0x1a;
-my $LANGUAGE_VERSION  = 0x04;
+my $LANGUAGE_VERSION  = 0x05;
+my $LANGUAGE_FLAG_RTL = 0x01;
 
 # A note for future users and readers: The original v1 language system allowed
 # the build to create and use a different language than english built-in. We
@@ -167,6 +168,12 @@
     $phrase{$n}=$v;
 }
 
+my %options;
+sub options {
+    my ($full, $n, $v)=@_;
+    $options{$n}=$v;
+}
+
 sub parsetarget {
     my ($debug, $strref, $full, $n, $v)=@_;
     my $string;
@@ -381,6 +388,8 @@
 open(LANG, "<$input") || die "Error: couldn't read language file named $input\n";
 my @phrase;
 my $header = 1;
+my $langoptions = 0;
+
 while(<LANG>) {
 
     $line++;
@@ -510,9 +519,15 @@
                         print "### $idstr: The phrase is not used. Skipped\n";
                     }
                 }
-                undef @phrase;
-
             } # end of </phrase>
+            elsif($part eq "/options") {
+                # closing the options
+                if ($options{'rtl'}) {
+                    $langoptions |= $LANGUAGE_FLAG_RTL;
+                }
+            } # end of </options>
+
+           undef @phrase;
 
             # starts with a slash, this _ends_ this section
             $m = pop @m; # get back old value, the previous level's tag
@@ -661,7 +676,8 @@
 
     open(OUTF, ">$binary") or die "Error: Can't create $binary";
     binmode OUTF;
-    printf OUTF ("%c%c%c", $LANGUAGE_COOKIE, $LANGUAGE_VERSION, $target_id); # magic lang file header
+    printf OUTF ("%c%c%c%c", $LANGUAGE_COOKIE, $LANGUAGE_VERSION, $target_id,
+      $langoptions); # magic lang file header
 
     # loop over the target phrases
     for $i (1 .. $idcount) {