diff --git a/DataExtractionOSM/.classpath b/DataExtractionOSM/.classpath
index c3c0f5d5da..1a233d7c17 100644
--- a/DataExtractionOSM/.classpath
+++ b/DataExtractionOSM/.classpath
@@ -15,5 +15,6 @@
+
diff --git a/DataExtractionOSM/lib/icu4j-49_1.jar b/DataExtractionOSM/lib/icu4j-49_1.jar
new file mode 100644
index 0000000000..ed1950c2b5
Binary files /dev/null and b/DataExtractionOSM/lib/icu4j-49_1.jar differ
diff --git a/DataExtractionOSM/src-tests/net/osmand/data/ArabicShaper.java b/DataExtractionOSM/src-tests/net/osmand/data/ArabicShaper.java
new file mode 100644
index 0000000000..84a6c04cf2
--- /dev/null
+++ b/DataExtractionOSM/src-tests/net/osmand/data/ArabicShaper.java
@@ -0,0 +1,28 @@
+package net.osmand.data;
+
+import com.ibm.icu.text.ArabicShaping;
+import com.ibm.icu.text.ArabicShapingException;
+import com.ibm.icu.text.Bidi;
+
+public class ArabicShaper {
+
+
+ public static void main(String[] args) throws ArabicShapingException {
+
+ ArabicShaping as = new ArabicShaping(ArabicShaping.LETTERS_SHAPE |
+ ArabicShaping.LENGTH_GROW_SHRINK);
+ String s = "אנשים 12";
+// for (int i = 0; i < s.length(); i++) {
+// System.out.println(s.charAt(i));
+// }
+ Bidi bd = new Bidi(s.length(), s.length());
+ bd.setPara(s, Bidi.LEVEL_DEFAULT_LTR, null);
+ System.out.println(bd.baseIsLeftToRight());
+ String r = as.shape(s);
+// for (int i = 0; i < r.length(); i++) {
+// System.out.println(r.charAt(i));
+// }
+ System.out.println(r);
+ }
+
+}
diff --git a/DataExtractionOSM/src/net/osmand/Reshaper.java b/DataExtractionOSM/src/net/osmand/Reshaper.java
new file mode 100644
index 0000000000..ec9e0262f8
--- /dev/null
+++ b/DataExtractionOSM/src/net/osmand/Reshaper.java
@@ -0,0 +1,89 @@
+package net.osmand;
+
+
+import org.apache.commons.logging.Log;
+
+import com.ibm.icu.text.ArabicShaping;
+import com.ibm.icu.text.ArabicShapingException;
+import com.ibm.icu.text.Bidi;
+import com.ibm.icu.text.BidiRun;
+
+public class Reshaper {
+ private final static Log LOG = LogUtil.getLog(Reshaper.class);
+
+ public static String reshape(String s) {
+// if(true) {
+// return s;
+// }
+ try {
+ ArabicShaping as = new ArabicShaping(ArabicShaping.LETTERS_SHAPE | ArabicShaping.LENGTH_GROW_SHRINK);
+ try {
+ s = as.shape(s);
+ } catch (ArabicShapingException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ Bidi line = new Bidi(s.length(), s.length());
+ line.setPara(s, Bidi.LEVEL_DEFAULT_LTR, null);
+ byte direction = line.getDirection();
+ if (direction != Bidi.MIXED) {
+ // unidirectional
+ if(line.isLeftToRight()) {
+ return s;
+ } else {
+ char[] chs = new char[s.length()];
+ for(int i = 0; i< chs.length ; i++) {
+ chs[i] = s.charAt(chs.length - i - 1);
+ }
+ return new String(chs);
+ }
+ } else {
+ // // mixed-directional
+ int count = line.countRuns();
+ // if (styleRunCount <= 1) {
+ // int style = styleRuns[0].style;
+ // // iterate over directional runs
+ // for (i = 0; i < count; ++i) {
+ // run = line.getVisualRun(i);
+ // renderRun(text, run.getStart(), run.getLimit(),
+ // run.getDirection(), style);
+ // }
+ // }
+ StringBuilder res = new StringBuilder();
+ // iterate over both directional and style runs
+ for (int i = 0; i < count; ++i) {
+ BidiRun run = line.getVisualRun(i);
+
+ int st = run.getStart();
+ int e = run.getLimit();
+ int j = run.getDirection() == Bidi.LTR ? st : e - 1;
+ int l = run.getDirection() == Bidi.LTR ? e : st - 1;
+ boolean plus = run.getDirection() == Bidi.LTR;
+ while (j != l) {
+ res.append(s.charAt(j));
+ if (plus) {
+ j++;
+ } else {
+ j--;
+ }
+ }
+ }
+ return res.toString();
+ }
+ } catch (RuntimeException e) {
+ LOG.error(e.getMessage(), e);
+ return s;
+ }
+
+ }
+
+ public static void main(String[] args) {
+// char[] c = new char[] {'א', 'ד','ם', ' ', '1', '2'} ;
+// String reshape = "אדם";
+ char[] c = new char[] {'א', 'ד','ם'} ;
+ String reshape = reshape(new String(c));
+ for(int i=0; i < reshape.length(); i++) {
+ System.out.println(reshape.charAt(i));
+ }
+ }
+
+}
diff --git a/OsmAnd/lib/icu4j-49_1.jar b/OsmAnd/lib/icu4j-49_1.jar
new file mode 100644
index 0000000000..ed1950c2b5
Binary files /dev/null and b/OsmAnd/lib/icu4j-49_1.jar differ
diff --git a/OsmAnd/libs/icu4j-49_1.jar b/OsmAnd/libs/icu4j-49_1.jar
new file mode 100644
index 0000000000..ed1950c2b5
Binary files /dev/null and b/OsmAnd/libs/icu4j-49_1.jar differ
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 4ade06fa3e..78da3cb079 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -9,7 +9,13 @@
1. All your modified/created strings are in the top of the file (to make easier find what's translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
-
+ Changes in 0.8.2 :
+ \n\t* Improved Routing
+ \n\t* Dynamic map widgets
+ \n\t* Map settings moved to map screen
+ \n\t* Lock screen button with logging services
+ \n\t* Fixed Arabic, Kannada scripting and RTL languages
+
Osmand is open source navigation application with raster/vector maps
Osmand (Open Street Maps Android)
@@ -114,12 +120,6 @@ OsmAnd is still in active development and relies on "donations" based support to
Show speed cameras
Show speed limits
Avoid toll roads
- Changes in 0.8.2 :
- \n\t* Improved Routing
- \n\t* Dynamic map widgets
- \n\t* Map settings moved to map screen
- \n\t* Lock screen button with logging services
-
Previous navigation was unfinished. Continue following it? (%1$s seconds)
Route will be recalculated when location will be found
Hours
diff --git a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java
index b1ab85fd3c..8d4abeacb9 100644
--- a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java
@@ -230,7 +230,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity {
favoritesToDelete.remove(model);
}
} else {
- QuickAction qa = new QuickAction(v);
+ final QuickAction qa = new QuickAction(v);
final OsmandSettings settings = getMyApplication().getSettings();
final FavouritePoint point = (FavouritePoint) favouritesAdapter.getChild(groupPosition, childPosition);
String name = getString(R.string.favorite) + ": " + point.getName();
@@ -238,7 +238,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity {
OnClickListener onshow = new OnClickListener() {
@Override
public void onClick(View v) {
- settings.SHOW_FAVORITES.set(true);
+ settings.SHOW_FAVORITES.set(true);
}
};
MapActivityActions.createDirectionsActions(qa, location, point, name, settings.getLastKnownMapZoom(), this,
@@ -250,6 +250,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity {
@Override
public void onClick(View v) {
editPoint(point);
+ qa.dismiss();
}
});
qa.addActionItem(edit);
@@ -260,6 +261,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity {
@Override
public void onClick(View v) {
deletePoint(point);
+ qa.dismiss();
}
});
qa.addActionItem(delete);
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index dda461b109..55a26b3b97 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -1073,7 +1073,7 @@ public class MapActivityActions implements DialogProvider {
menu.show();
}
- public static void createDirectionsActions(QuickAction qa , final LatLon location, final Object obj, final String name, final int z, final Activity activity,
+ public static void createDirectionsActions(final QuickAction qa , final LatLon location, final Object obj, final String name, final int z, final Activity activity,
final boolean saveHistory, final OnClickListener onShow){
ActionItem showOnMap = new ActionItem();
final OsmandApplication app = ((OsmandApplication) activity.getApplication());
@@ -1088,6 +1088,7 @@ public class MapActivityActions implements DialogProvider {
app.getSettings().setMapLocationToShow( location.getLatitude(), location.getLongitude(),
z, saveHistory ? name : null, name, obj); //$NON-NLS-1$
MapActivity.launchMapActivityMoveToTop(activity);
+ qa.dismiss();
}
});
qa.addActionItem(showOnMap);
@@ -1102,6 +1103,7 @@ public class MapActivityActions implements DialogProvider {
}
app.getSettings().setPointToNavigate(location.getLatitude(), location.getLongitude(), name);
MapActivity.launchMapActivityMoveToTop(activity);
+ qa.dismiss();
}
});
qa.addActionItem(setAsDestination);
@@ -1117,6 +1119,7 @@ public class MapActivityActions implements DialogProvider {
}
app.getSettings().setPointToNavigate(location.getLatitude(), location.getLongitude(), true, name);
MapActivity.launchMapActivityMoveToTop(activity);
+ qa.dismiss();
}
});
qa.addActionItem(directionsTo);
diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java
index b559e4d901..c7f9184067 100644
--- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java
@@ -516,7 +516,7 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent
@Override
public void onListItemClick(ListView parent, View v, int position, long id) {
final Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position);
- QuickAction qa = new QuickAction(v);
+ final QuickAction qa = new QuickAction(v);
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
String name = getString(R.string.poi)+" : " + poiSimpleFormat;
int z = Math.max(16, settings.getLastKnownMapZoom());
diff --git a/Osmand-kernel/osmand/src/common.cpp b/Osmand-kernel/osmand/src/common.cpp
index 22113f11cf..33773f673e 100644
--- a/Osmand-kernel/osmand/src/common.cpp
+++ b/Osmand-kernel/osmand/src/common.cpp
@@ -167,6 +167,10 @@ std::string RenderingContext::getTranslatedString(const std::string& src) {
return src;
}
+std::string RenderingContext::getReshapedString(const std::string& src) {
+ return src;
+}
+
inline double getPowZoom(float zoom){
if(zoom >= 0 && zoom - floor(zoom) < 0.05f){
diff --git a/Osmand-kernel/osmand/src/common.h b/Osmand-kernel/osmand/src/common.h
index 4ed5d658f6..21131f0765 100644
--- a/Osmand-kernel/osmand/src/common.h
+++ b/Osmand-kernel/osmand/src/common.h
@@ -195,6 +195,7 @@ public:
virtual bool interrupted();
virtual SkBitmap* getCachedBitmap(const std::string& bitmapResource);
virtual std::string getTranslatedString(const std::string& src);
+ virtual std::string getReshapedString(const std::string& src);
void setDefaultIconsDir(string path) {
defaultIconsDir = path;
diff --git a/Osmand-kernel/osmand/src/java_wrap.cpp b/Osmand-kernel/osmand/src/java_wrap.cpp
index d371057344..03ec1e3ba6 100644
--- a/Osmand-kernel/osmand/src/java_wrap.cpp
+++ b/Osmand-kernel/osmand/src/java_wrap.cpp
@@ -349,7 +349,9 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_generateRende
////////// JNI Rendering Context //////////////
jclass jclass_JUnidecode;
+jclass jclass_Reshaper;
jmethodID jmethod_JUnidecode_unidecode;
+jmethodID jmethod_Reshaper_reshape;
jclass jclass_RenderingContext = NULL;
jfieldID jfield_RenderingContext_interrupted = NULL;
jfieldID jfield_RenderingContext_leftX = NULL;
@@ -417,6 +419,8 @@ void loadJniRenderingContext(JNIEnv* env)
jclass_JUnidecode = findClass(env, "net/sf/junidecode/Junidecode");
jmethod_JUnidecode_unidecode = env->GetStaticMethodID(jclass_JUnidecode, "unidecode", "(Ljava/lang/String;)Ljava/lang/String;");
+ jclass_Reshaper = findClass(env, "net/osmand/Reshaper");
+ jmethod_Reshaper_reshape = env->GetStaticMethodID(jclass_Reshaper, "reshape", "(Ljava/lang/String;)Ljava/lang/String;");
jclass_RouteDataObject = findClass(env, "net/osmand/binary/RouteDataObject");
jclass_NativeRouteSearchResult = findClass(env, "net/osmand/NativeLibrary$NativeRouteSearchResult");
@@ -666,3 +670,12 @@ std::string JNIRenderingContext::getTranslatedString(const std::string& name) {
return name;
}
+std::string JNIRenderingContext::getReshapedString(const std::string& name) {
+ jstring n = this->env->NewStringUTF(name.c_str());
+ jstring translate = (jstring) this->env->CallStaticObjectMethod(jclass_Reshaper, jmethod_Reshaper_reshape, n);
+ std::string res = getString(this->env, translate);
+ this->env->DeleteLocalRef(translate);
+ this->env->DeleteLocalRef(n);
+ return res;
+}
+
diff --git a/Osmand-kernel/osmand/src/java_wrap.h b/Osmand-kernel/osmand/src/java_wrap.h
index f60dc09554..cf96cfd751 100644
--- a/Osmand-kernel/osmand/src/java_wrap.h
+++ b/Osmand-kernel/osmand/src/java_wrap.h
@@ -29,6 +29,8 @@ struct JNIRenderingContext : RenderingContext
virtual SkBitmap* getCachedBitmap(const std::string& bitmapResource);
virtual std::string getTranslatedString(const std::string& src);
+ virtual std::string getReshapedString(const std::string& src);
+
virtual bool interrupted();
virtual ~JNIRenderingContext(){}
};
diff --git a/Osmand-kernel/osmand/src/rendering.cpp b/Osmand-kernel/osmand/src/rendering.cpp
index 2a601e88aa..7eef978f8e 100644
--- a/Osmand-kernel/osmand/src/rendering.cpp
+++ b/Osmand-kernel/osmand/src/rendering.cpp
@@ -208,6 +208,7 @@ void renderText(MapDataObject* obj, RenderingRuleSearchRequest* req, RenderingCo
if (it->second.length() > 0) {
std::string name = it->second;
name =rc->getTranslatedString(name);
+ name =rc->getReshapedString(name);
req->setInitialTagValueZoom(tag, value, rc->getZoom(), obj);
req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length());
std::string tagName = it->first == "name" ? "" : it->first;