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;