RTL language enhancements by Tomers Shalev and I.

3 new tokens:
%ax - the next token should follow the language direction (what that means is defined by the individual tokens)
%aL - align left on LTR language (same as %al), right on RTL languages
%aR - align right on LTR language (same as %ar), left on RTL languages

This commit adds %ax support to the %V and %Cl tokens. 


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24193 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/filetree.c b/apps/filetree.c
index e5da824..ccf4c2b 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -548,6 +548,7 @@
                         MAX_FILENAME);
                 talk_init(); /* use voice of same language */
                 viewportmanager_theme_changed(THEME_LANGUAGE);
+                settings_apply_skins();
                 splash(HZ, ID2P(LANG_LANGUAGE_LOADED));
                 break;
 
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index ea2c794..b8cc75e 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -31,6 +31,7 @@
 #endif
 #include "abrepeat.h"
 #include "lang.h"
+#include "language.h"
 #include "statusbar.h"
 #include "scrollbar.h"
 #include "screen_access.h"
@@ -528,8 +529,10 @@
 #endif
 
             case WPS_TOKEN_ALIGN_LEFT:
+            case WPS_TOKEN_ALIGN_LEFT_RTL:
             case WPS_TOKEN_ALIGN_CENTER:
             case WPS_TOKEN_ALIGN_RIGHT:
+            case WPS_TOKEN_ALIGN_RIGHT_RTL:
                 /* remember where the current aligned text started */
                 switch (cur_align)
                 {
@@ -551,12 +554,20 @@
                     case WPS_TOKEN_ALIGN_LEFT:
                         cur_align = WPS_ALIGN_LEFT;
                         break;
+                    case WPS_TOKEN_ALIGN_LEFT_RTL:
+                        cur_align = lang_is_rtl() ? WPS_ALIGN_RIGHT :
+                            WPS_ALIGN_LEFT;
+                        break;
                     case WPS_TOKEN_ALIGN_CENTER:
                         cur_align = WPS_ALIGN_CENTER;
                         break;
                     case WPS_TOKEN_ALIGN_RIGHT:
                         cur_align = WPS_ALIGN_RIGHT;
                         break;
+                    case WPS_TOKEN_ALIGN_RIGHT_RTL:
+                        cur_align = lang_is_rtl() ? WPS_ALIGN_LEFT :
+                            WPS_ALIGN_RIGHT;
+                        break;
                     default:
                         break;
                 }
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 568f9cb..1e24762 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -89,6 +89,8 @@
 /* the current line, linked to the above viewport */
 static struct skin_line *curr_line;
 
+static int follow_lang_direction = 0;
+
 #ifdef HAVE_LCD_BITMAP
 
 #if LCD_DEPTH > 1
@@ -140,6 +142,19 @@
         struct wps_token *token, struct wps_data *wps_data);
 static int parse_setting_and_lang(const char *wps_bufptr,
         struct wps_token *token, struct wps_data *wps_data);
+        
+        
+int parse_languagedirection(const char *wps_bufptr,
+        struct wps_token *token, struct wps_data *wps_data)
+{
+    (void)wps_bufptr;
+    (void)token;
+    (void)wps_data;
+    follow_lang_direction = 2; /* 2 because it is decremented immediatly after 
+                                  this token is parsed, after the next token it 
+                                  will be 0 again. */
+    return 0;
+}
 
 #ifdef HAVE_LCD_BITMAP
 static int parse_viewport_display(const char *wps_bufptr,
@@ -189,7 +204,10 @@
 
     { WPS_TOKEN_ALIGN_CENTER,             "ac",  0,                   NULL },
     { WPS_TOKEN_ALIGN_LEFT,               "al",  0,                   NULL },
+    { WPS_TOKEN_ALIGN_LEFT_RTL,           "aL",  0,                   NULL },
     { WPS_TOKEN_ALIGN_RIGHT,              "ar",  0,                   NULL },
+    { WPS_TOKEN_ALIGN_RIGHT_RTL,          "aR",  0,                   NULL },
+    { WPS_NO_TOKEN,                       "ax",  0,   parse_languagedirection },
 
     { WPS_TOKEN_BATTERY_PERCENT,          "bl",  WPS_REFRESH_DYNAMIC, NULL },
     { WPS_TOKEN_BATTERY_VOLTS,            "bv",  WPS_REFRESH_DYNAMIC, NULL },
@@ -748,15 +766,22 @@
     ptr++;
     struct viewport *vp = &skin_vp->vp;
     /* format: %V|x|y|width|height|font|fg_pattern|bg_pattern| */
-
     if (!(ptr = viewport_parse_viewport(vp, curr_screen, ptr, '|')))
         return WPS_ERROR_INVALID_PARAM;
-
-    vp->flags &= ~VP_FLAG_ALIGN_RIGHT; /* ignore right-to-left languages */
+        
     /* Check for trailing | */
     if (*ptr != '|')
         return WPS_ERROR_INVALID_PARAM;
 
+    if (follow_lang_direction && lang_is_rtl())
+    {
+        vp->flags |= VP_FLAG_ALIGN_RIGHT;
+        vp->x = screens[curr_screen].lcdwidth - vp->width - vp->x;
+    }
+    else
+        vp->flags &= ~VP_FLAG_ALIGN_RIGHT; /* ignore right-to-left languages */
+
+
 
     struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp);
     if (!list)
@@ -954,6 +979,7 @@
     }
     pb->have_bitmap_pb = false;
     pb->bm.data = NULL; /* no bitmap specified */
+    pb->follow_lang_direction = follow_lang_direction > 0;
 
     if (*wps_bufptr != '|') /* regular old style */
     {
@@ -1041,6 +1067,7 @@
     bool parsing;
     struct dim dimensions;
     int albumart_slot;
+    bool swap_for_rtl = lang_is_rtl() && follow_lang_direction;
     struct skin_albumart *aa = skin_buffer_alloc(sizeof(struct skin_albumart));
     (void)token; /* silence warning */
     if (!aa)
@@ -1085,7 +1112,10 @@
             case 'l':
             case 'L':
             case '+':
-                aa->xalign = WPS_ALBUMART_ALIGN_LEFT;
+                if (swap_for_rtl)
+                    aa->xalign = WPS_ALBUMART_ALIGN_RIGHT;
+                else
+                    aa->xalign = WPS_ALBUMART_ALIGN_LEFT;
                 break;
             case 'c':
             case 'C':
@@ -1094,7 +1124,10 @@
             case 'r':
             case 'R':
             case '-':
-                aa->xalign = WPS_ALBUMART_ALIGN_RIGHT;
+                if (swap_for_rtl)
+                    aa->xalign = WPS_ALBUMART_ALIGN_LEFT;
+                else
+                    aa->xalign = WPS_ALBUMART_ALIGN_RIGHT;
                 break;
             case 'd':
             case 'D':
@@ -1168,6 +1201,9 @@
         aa->height = 0;
     else if (aa->height > LCD_HEIGHT)
         aa->height = LCD_HEIGHT;
+        
+    if (swap_for_rtl)
+        aa->x = LCD_WIDTH - (aa->x + aa->width);
 
     aa->state = WPS_ALBUMART_LOAD;
     aa->draw = false;
@@ -1500,6 +1536,8 @@
 
     while (*wps_bufptr && !fail)
     {
+        if (follow_lang_direction)
+            follow_lang_direction--;
         /* first make sure there is enough room for tokens */
         if (max_tokens <= data->num_tokens + 5)
         {
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
index 547bc85..25acfda 100644
--- a/apps/gui/skin_engine/skin_tokens.h
+++ b/apps/gui/skin_engine/skin_tokens.h
@@ -38,8 +38,10 @@
 
     /* Alignment */
     WPS_TOKEN_ALIGN_LEFT,
+    WPS_TOKEN_ALIGN_LEFT_RTL,
     WPS_TOKEN_ALIGN_CENTER,
     WPS_TOKEN_ALIGN_RIGHT,
+    WPS_TOKEN_ALIGN_RIGHT_RTL,
 
     /* Sublines */
     WPS_TOKEN_SUBLINE_TIMEOUT,
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index e975616..bd0c1c0 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -99,6 +99,7 @@
     short y;
     short width;
     short height;
+    bool  follow_lang_direction;
     /*progressbar image*/
     struct bitmap bm;
     bool have_bitmap_pb;
diff --git a/wps/cabbiev2.128x128x16.wps b/wps/cabbiev2.128x128x16.wps
index 95eac03..bce8b94 100644
--- a/wps/cabbiev2.128x128x16.wps
+++ b/wps/cabbiev2.128x128x16.wps
@@ -9,8 +9,8 @@
 %xl|D|shuffle-128x128x16.bmp|74|110|
 %xl|E|repeat-128x128x16.bmp|97|110|4|
 %xl|F|playmode-128x128x16.bmp|111|110|5|
-%Cl|4|12|s60|s60|
-%pb|pb-128x128x16.bmp|3|87|122|6|
+%ax%Cl|4|12|s60|s60|
+%ax%pb|pb-128x128x16.bmp|3|87|122|6|
 # images all in the default viewport
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
@@ -23,7 +23,7 @@
 
 
 #NowPlaying - with AA
-%Vl|a|70|12|-|50|1|-|-|
+%ax%Vl|a|70|12|-|50|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -40,4 +40,4 @@
 %V|3|70|122|18|1|-|-|
 %s%ac%Sx|Next:|%?It<%It|%Fn>
 
-%al%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr
+%aL%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%aR%pr
diff --git a/wps/cabbiev2.132x80x16.wps b/wps/cabbiev2.132x80x16.wps
index 279d314..6657b01 100644
--- a/wps/cabbiev2.132x80x16.wps
+++ b/wps/cabbiev2.132x80x16.wps
@@ -8,8 +8,8 @@
 %xl|D|shuffle-132x80x16.bmp|86|69|
 %xl|E|repeat-132x80x16.bmp|105|67|4|
 %xl|F|playmode-132x80x16.bmp|118|67|5|
-%Cl|3|14|c40|c40|
-%pb|pb-132x80x16.bmp|2|58|127|6|
+%ax%Cl|3|14|c40|c40|
+%ax%pb|pb-132x80x16.bmp|2|58|127|6|
 %?C<%C%Vda|%Vdb>
 
 #Images
@@ -21,7 +21,7 @@
 %?mp<%xdFa|%xdFb|%xdFc|%xdFd|%xdFe>
 
 #NowPlaying - aa
-%Vl|a|48|10|-|48|1|-|-|
+%ax%Vl|a|48|10|-|48|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
diff --git a/wps/cabbiev2.138x110x2.wps b/wps/cabbiev2.138x110x2.wps
index 2437193..4c74dda 100644
--- a/wps/cabbiev2.138x110x2.wps
+++ b/wps/cabbiev2.138x110x2.wps
@@ -10,8 +10,8 @@
 %xl|D|shuffle-160x128x2.bmp|78|97|
 %xl|E|repeat-160x128x2.bmp|102|97|4|
 %xl|F|playmode-160x128x2.bmp|123|98|5|
-%Cl|5|15|s55|s55|
-%pb|pb-138x110x2.bmp|2|75|134|6|
+%ax%Cl|5|15|s55|s55|
+%ax%pb|pb-138x110x2.bmp|2|75|134|6|
 #images
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
@@ -21,7 +21,7 @@
 %?mp<%xdFa|%xdFb|%xdFc|%xdFd|%xdFe>
 %?C<%C%Vda|%Vdb>
 
-%Vl|a|65|10|-|60|1|-|-|
+%ax%Vl|a|65|10|-|60|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -36,4 +36,4 @@
 %s%ac%?It<%It|%Fn>
 
 %V|2|82|134|13|1|-|-|
-%al%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr
+%aL%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%aR%pr
diff --git a/wps/cabbiev2.160x128x16.wps b/wps/cabbiev2.160x128x16.wps
index d437593..c7bdbc7 100644
--- a/wps/cabbiev2.160x128x16.wps
+++ b/wps/cabbiev2.160x128x16.wps
@@ -9,8 +9,8 @@
 %xl|D|shuffle-160x128x16.bmp|104|116|
 %xl|E|repeat-160x128x16.bmp|125|112|4|
 %xl|F|playmode-160x128x16.bmp|142|114|5|
-%Cl|7|16|c65|c65|
-%pb|pb-160x128x16.bmp|6|86|149|8|
+%ax%Cl|7|16|c65|c65|
+%ax%pb|pb-160x128x16.bmp|6|86|149|8|
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
 %?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
@@ -20,7 +20,7 @@
 %?C<%C%Vda|%Vdb>
 
 # NowPlaying - AA
-%Vl|a|77|10|-|75|1|-|-|
+%ax%Vl|a|77|10|-|75|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -38,5 +38,5 @@
 %s%?It<%It|%Fn>
 
 %V|6|96|149|10|1|-|-|
-%al%pc%ac%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr%ar%pr
+%aL%pc%ac%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr%aR%pr
 
diff --git a/wps/cabbiev2.160x128x2.wps b/wps/cabbiev2.160x128x2.wps
index 4ccb180..5b41c24 100644
--- a/wps/cabbiev2.160x128x2.wps
+++ b/wps/cabbiev2.160x128x2.wps
@@ -11,8 +11,8 @@
 %xl|D|shuffle-160x128x2.bmp|107|115|
 %xl|E|repeat-160x128x2.bmp|127|113|4|
 %xl|F|playmode-160x128x2.bmp|145|114|5|
-%Cl|2|16|s64|s64|
-%pb|pb-160x128x2.bmp|1|86|158|8|
+%ax%Cl|2|16|s64|s64|
+%ax%pb|pb-160x128x2.bmp|1|86|158|8|
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
 %?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
@@ -21,7 +21,7 @@
 %?mp<%xdFa|%xdFb|%xdFc|%xdFd|%xdFe>
 %?C<%C%Vda|%Vdb>
 
-%Vl|a|70|10|-|75|1|-|-|
+%ax%Vl|a|70|10|-|75|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -38,5 +38,5 @@
 %s%ac%?It<%It|%Fn>
 
 %V|1|96|158|10|1|-|-|
-%al%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr
+%aL%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%aR%pr
 
diff --git a/wps/cabbiev2.176x132x16.wps b/wps/cabbiev2.176x132x16.wps
index a400c18..8a40eef 100644
--- a/wps/cabbiev2.176x132x16.wps
+++ b/wps/cabbiev2.176x132x16.wps
@@ -10,8 +10,8 @@
 %xl|D|shuffle-176x132x16.bmp|120|117|
 %xl|E|repeat-176x132x16.bmp|139|113|4|
 %xl|F|playmode-176x132x16.bmp|156|115|5|
-%Cl|9|16|s65|s65|
-%pb|pb-176x132x16.bmp|8|86|160|8|
+%ax%Cl|9|16|s65|s65|
+%ax%pb|pb-176x132x16.bmp|8|86|160|8|
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
 %?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
@@ -21,7 +21,7 @@
 %?C<%C%Vda|%Vdb>
 
 #NowPlaying
-%Vl|a|81|12|-|74|1|-|-|
+%ax%Vl|a|81|12|-|74|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
diff --git a/wps/cabbiev2.220x176x16.wps b/wps/cabbiev2.220x176x16.wps
index c5bd219..352386f 100644
--- a/wps/cabbiev2.220x176x16.wps
+++ b/wps/cabbiev2.220x176x16.wps
@@ -9,8 +9,8 @@
 %xl|D|shuffle-220x176x16.bmp|155|153|
 %xl|E|repeat-220x176x16.bmp|182|151|4|
 %xl|F|playmode-220x176x16.bmp|200|152|5|
-%Cl|15|32|s75|s75|
-%pb|pb-220x176x16.bmp|11|121|199|8|
+%ax%Cl|15|32|s75|s75|
+%ax%pb|pb-220x176x16.bmp|11|121|199|8|
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
 %?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
@@ -21,7 +21,7 @@
 #NowPlaying
 %?C<%Vda%C|%Vdb>
 
-%Vl|a|105|30|-|90|1|-|-|
+%ax%Vl|a|105|30|-|90|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -39,4 +39,4 @@
 
 
 %V|11|130|199|20|1|-|-|
-%al%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr
+%aL%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%aR%pr
diff --git a/wps/cabbiev2.320x240x16.wps b/wps/cabbiev2.320x240x16.wps
index 7efa3f3..9ba15b6 100644
--- a/wps/cabbiev2.320x240x16.wps
+++ b/wps/cabbiev2.320x240x16.wps
@@ -9,8 +9,8 @@
 %xl|D|shuffle-320x240x16.bmp|218|211|
 %xl|E|repeat-320x240x16.bmp|261|207|4|
 %xl|F|playmode-320x240x16.bmp|286|207|5|
-%Cl|16|32|s120|s120|
-%pb|pb-320x240x16.bmp|10|162|300|15|
+%ax%Cl|16|32|s120|s120|
+%ax%pb|pb-320x240x16.bmp|10|162|300|15|
 %?mh<%xdAa|%xdAb>
 %?bp<%?bc<%xdBa|%xdBb>|%?bl<|%xdBc|%xdBd|%xdBe|%xdBf|%xdBg|%xdBh|%xdBi|%xdBj>>
 %?pv<%xdCa|%xdCb|%xdCc|%xdCd|%xdCe|%xdCf|%xdCg|%xdCh|%xdCi|%xdCj>
@@ -21,7 +21,7 @@
 %?C<%Vda%C|%Vdb>
 #NowPlaying
 
-%Vl|a|153|30|-|130|1|-|-|
+%ax%Vl|a|153|30|-|130|1|-|-|
 %s%al%?it<%it|%fn>
 %s%al%?ia<%ia|%?d2<%d2|(root)>>
 %s%al%?id<%id|%?d1<%d1|(root)>>
@@ -31,7 +31,7 @@
 %s%al%?It<%It|%Fn>
 %s%al%Ia
 
-%Vl|b|0|30|-|130|1|-|-|
+%ax%Vl|b|0|30|-|130|1|-|-|
 %s%ac%?it<%it|%fn>
 %s%ac%?ia<%ia|%?d2<%d2|(root)>>
 %s%ac%?id<%id|%?d1<%d1|(root)>>
@@ -42,5 +42,5 @@
 %s%ac%Ia
 
 %V|10|180|300|20|1|-|-|
-%al%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%ar%pr
+%aL%pc%ac%?Sr<%pe %Sx|of| %pp|%pp %Sx|of| %pe>%aR%pr