Compare commits
43 Commits
6a20269819
...
test/2025.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
498dcc4240 | ||
|
|
67d88b4fa9 | ||
|
|
4f443edc13 | ||
|
|
a883dfb7ff | ||
|
|
568bd8a3cc | ||
|
|
d81a9958be | ||
|
|
8b9440f407 | ||
|
|
f5437c725c | ||
|
|
42d2b4e2a9 | ||
|
|
8f12b53d62 | ||
|
|
2d8ef64b17 | ||
|
|
15b919cf72 | ||
|
|
94aa41cf44 | ||
|
|
16381cdebd | ||
|
|
bc740aceb8 | ||
|
|
794d5c872e | ||
|
|
095040a060 | ||
|
|
30e5657c4f | ||
|
|
9d38deff1c | ||
|
|
b5068c9915 | ||
|
|
4178148e47 | ||
|
|
97d5178c72 | ||
|
|
68b90d3c2e | ||
|
|
4582972591 | ||
|
|
624f364805 | ||
|
|
4e7c968beb | ||
|
|
29ab48dc49 | ||
|
|
cfcff9f882 | ||
|
|
44d281e109 | ||
|
|
8a92018efe | ||
|
|
fd873dfc88 | ||
|
|
b052b26081 | ||
|
|
764a0758c5 | ||
|
|
d5e0889c9a | ||
|
|
a1a13caa4e | ||
|
|
c75d1fc79d | ||
|
|
3195ef6c3b | ||
|
|
cf43bf6b1c | ||
|
|
9966cee168 | ||
|
|
023afecaa2 | ||
|
|
6e7ba078c8 | ||
|
|
b39631fe51 | ||
|
|
d2fee9ff8e |
@@ -10,6 +10,7 @@ CoMaps contributors:
|
||||
Bastian Greshake Tzovaras
|
||||
clover sage
|
||||
Harry Bond <me@hbond.xyz>
|
||||
NoelClick
|
||||
thesupertechie
|
||||
vikiawv
|
||||
Yannik Bloscheck
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.CallSuper;
|
||||
@@ -25,7 +26,15 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import app.organicmaps.base.BaseMwmFragmentActivity;
|
||||
import app.organicmaps.dialog.CustomMapServerDialog;
|
||||
import app.organicmaps.downloader.MapManagerHelper;
|
||||
import app.organicmaps.intent.Factory;
|
||||
import app.organicmaps.sdk.Framework;
|
||||
@@ -38,11 +47,7 @@ import app.organicmaps.sdk.util.StringUtils;
|
||||
import app.organicmaps.util.UiUtils;
|
||||
import app.organicmaps.util.Utils;
|
||||
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -54,6 +59,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
||||
private MaterialTextView mTvMessage;
|
||||
private LinearProgressIndicator mProgress;
|
||||
private MaterialButton mBtnDownload;
|
||||
private MaterialButton mBtnAdvanced;
|
||||
private MaterialCheckBox mChbDownloadCountry;
|
||||
|
||||
private String mCurrentCountry;
|
||||
@@ -267,6 +273,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
||||
mProgress = findViewById(R.id.progressbar);
|
||||
mBtnDownload = findViewById(R.id.btn_download_resources);
|
||||
mChbDownloadCountry = findViewById(R.id.chb_download_country);
|
||||
mBtnAdvanced = findViewById(R.id.btn_advanced);
|
||||
|
||||
mBtnAdvanced.setOnClickListener(v -> {
|
||||
CustomMapServerDialog.show(this, url -> {
|
||||
prepareFilesDownload(false);
|
||||
});
|
||||
});
|
||||
mBtnAdvanced.setEnabled(true);
|
||||
|
||||
mBtnListeners = new View.OnClickListener[BTN_COUNT];
|
||||
mBtnNames = new String[BTN_COUNT];
|
||||
@@ -291,6 +305,11 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
||||
{
|
||||
mBtnDownload.setOnClickListener(mBtnListeners[action]);
|
||||
mBtnDownload.setText(mBtnNames[action]);
|
||||
|
||||
// Allow changing server only when idle or after an error.
|
||||
boolean advancedEnabled = (action == DOWNLOAD || action == TRY_AGAIN || action == RESUME);
|
||||
mBtnAdvanced.setEnabled(advancedEnabled);
|
||||
mBtnAdvanced.setAlpha(advancedEnabled ? 1f : 0.5f);
|
||||
}
|
||||
|
||||
private void doDownload()
|
||||
@@ -359,6 +378,9 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
|
||||
|
||||
private void finishFilesDownload(int result)
|
||||
{
|
||||
mBtnAdvanced.setEnabled(true);
|
||||
mBtnAdvanced.setAlpha(1f);
|
||||
|
||||
if (result == ERR_NO_MORE_FILES)
|
||||
{
|
||||
// World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model.
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package app.organicmaps.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.sdk.Framework;
|
||||
|
||||
public final class CustomMapServerDialog
|
||||
{
|
||||
public interface OnUrlAppliedListener
|
||||
{
|
||||
void onUrlApplied(@NonNull String url);
|
||||
}
|
||||
|
||||
private CustomMapServerDialog() {}
|
||||
|
||||
public static void show(@NonNull Context context,
|
||||
@Nullable OnUrlAppliedListener listener)
|
||||
{
|
||||
View dialogView = LayoutInflater.from(context)
|
||||
.inflate(R.layout.dialog_custom_map_server, null);
|
||||
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
|
||||
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
|
||||
|
||||
SharedPreferences prefs =
|
||||
PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String current = prefs.getString(context.getString(R.string.pref_custom_map_download_url), "");
|
||||
edit.setText(current);
|
||||
|
||||
MaterialAlertDialogBuilder builder =
|
||||
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
|
||||
.setTitle(R.string.download_resources_custom_url_title)
|
||||
.setMessage(R.string.download_resources_custom_url_message)
|
||||
.setView(dialogView)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.save, null);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.setOnShowListener(dlg -> {
|
||||
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
ok.setOnClickListener(v -> {
|
||||
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
|
||||
|
||||
if (!url.isEmpty()
|
||||
&& !url.startsWith("http://")
|
||||
&& !url.startsWith("https://"))
|
||||
{
|
||||
til.setError(context.getString(R.string.download_resources_custom_url_error_scheme));
|
||||
return;
|
||||
}
|
||||
|
||||
til.setError(null);
|
||||
|
||||
String normalizedUrl = Framework.normalizeServerUrl(url);
|
||||
|
||||
prefs.edit()
|
||||
.putString(context.getString(R.string.pref_custom_map_download_url), normalizedUrl)
|
||||
.apply();
|
||||
|
||||
// Apply to native
|
||||
Framework.applyCustomMapDownloadUrl(context, normalizedUrl);
|
||||
|
||||
if (listener != null)
|
||||
listener.onUrlApplied(normalizedUrl);
|
||||
|
||||
dialog.dismiss();
|
||||
});
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,23 @@ import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.TwoStatePreference;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import app.organicmaps.MwmApplication;
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.dialog.CustomMapServerDialog;
|
||||
import app.organicmaps.downloader.OnmapDownloader;
|
||||
import app.organicmaps.editor.LanguagesFragment;
|
||||
import app.organicmaps.editor.ProfileActivity;
|
||||
@@ -35,7 +42,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
|
||||
import app.organicmaps.sdk.util.log.LogsManager;
|
||||
import app.organicmaps.util.ThemeSwitcher;
|
||||
import app.organicmaps.util.Utils;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -73,6 +80,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
|
||||
initScreenSleepEnabledPrefsCallbacks();
|
||||
initShowOnLockScreenPrefsCallbacks();
|
||||
initLeftButtonPrefs();
|
||||
initCustomMapDownloadUrlPrefsCallbacks();
|
||||
}
|
||||
|
||||
private void initLeftButtonPrefs()
|
||||
@@ -535,6 +543,34 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
|
||||
});
|
||||
}
|
||||
|
||||
private void initCustomMapDownloadUrlPrefsCallbacks()
|
||||
{
|
||||
Preference customUrlPref = getPreference(getString(R.string.pref_custom_map_download_url));
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
|
||||
|
||||
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
|
||||
String normalizedUrl = Framework.normalizeServerUrl(current);
|
||||
|
||||
// Initial summary
|
||||
customUrlPref.setSummary(normalizedUrl.isEmpty()
|
||||
? getString(R.string.download_resources_custom_url_summary_none)
|
||||
: normalizedUrl);
|
||||
|
||||
// Sync native
|
||||
Framework.applyCustomMapDownloadUrl(requireContext(), normalizedUrl);
|
||||
|
||||
// Show dialog
|
||||
customUrlPref.setOnPreferenceClickListener(preference -> {
|
||||
CustomMapServerDialog.show(requireContext(), url -> {
|
||||
preference.setSummary(url.isEmpty()
|
||||
? getString(R.string.download_resources_custom_url_summary_none)
|
||||
: url);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void removePreference(@NonNull String categoryKey, @NonNull Preference preference)
|
||||
{
|
||||
final PreferenceCategory category = getPreference(categoryKey);
|
||||
|
||||
@@ -700,11 +700,20 @@ public class PlacePageView extends Fragment
|
||||
|
||||
if (shouldEnableEditPlace)
|
||||
{
|
||||
mTvEditPlace.setEnabled(true);
|
||||
mTvAddPlace.setEnabled(true);
|
||||
mTvEditPlace.setOnClickListener(this);
|
||||
mTvAddPlace.setOnClickListener(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
String countryId = MapManager.nativeGetSelectedCountry();
|
||||
|
||||
if (countryId != null && MapManager.nativeIsMapTooOldToEdit(countryId))
|
||||
{
|
||||
// map editing is disabled because the map is too old
|
||||
mTvEditPlace.setEnabled(true);
|
||||
mTvAddPlace.setEnabled(true);
|
||||
mTvEditPlace.setOnClickListener((v) -> {
|
||||
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
|
||||
});
|
||||
@@ -712,10 +721,6 @@ public class PlacePageView extends Fragment
|
||||
Utils.showSnackbar(v.getContext(), v.getRootView(), R.string.place_page_too_old_to_edit);
|
||||
});
|
||||
|
||||
String countryId = MapManager.nativeGetSelectedCountry();
|
||||
|
||||
if (countryId != null)
|
||||
{
|
||||
CountryItem map = CountryItem.fill(countryId);
|
||||
|
||||
if (map.status == CountryItem.STATUS_UPDATABLE || map.status == CountryItem.STATUS_DONE
|
||||
@@ -740,6 +745,12 @@ public class PlacePageView extends Fragment
|
||||
mapTooOldDescription.setText(R.string.place_page_app_too_old_description);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// map editing is disabled for other reasons
|
||||
mTvEditPlace.setEnabled(false);
|
||||
mTvAddPlace.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
final int editButtonColor =
|
||||
|
||||
11
android/app/src/main/res/drawable/ic_cloud_download.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:tint="?colorControlNormal"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportHeight="960"
|
||||
android:viewportWidth="960">
|
||||
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M260,800Q169,800 104.5,737Q40,674 40,583Q40,505 87,444Q134,383 210,366Q227,294 295,229Q363,164 440,164Q473,164 496.5,187.5Q520,211 520,244L520,486L584,424L640,480L480,640L320,480L376,424L440,486L440,244Q364,258 322,317.5Q280,377 280,440L260,440Q202,440 161,481Q120,522 120,580Q120,638 161,679Q202,720 260,720L740,720Q782,720 811,691Q840,662 840,620Q840,578 811,549Q782,520 740,520L680,520L680,440Q680,392 658,350.5Q636,309 600,280L600,187Q674,222 717,290.5Q760,359 760,440L760,440L760,440Q829,448 874.5,499.5Q920,551 920,620Q920,695 867.5,747.5Q815,800 740,800L260,800ZM480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442Q480,442 480,442L480,442L480,442Q480,442 480,442Q480,442 480,442Z"/>
|
||||
|
||||
</vector>
|
||||
@@ -11,6 +11,18 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/button_container"
|
||||
android:layout_gravity="center">
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_advanced"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:icon="@drawable/ic_settings"
|
||||
app:iconTint="?iconTint"
|
||||
android:contentDescription="@string/download_resources_custom_url_title"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_margin="@dimen/margin_half" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
22
android/app/src/main/res/layout/dialog_custom_map_server.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/til_custom_map_server"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/margin_base"
|
||||
android:paddingEnd="@dimen/margin_base"
|
||||
android:paddingTop="@dimen/margin_base"
|
||||
android:paddingBottom="@dimen/margin_half"
|
||||
android:hint="@string/download_resources_custom_url_title"
|
||||
app:placeholderText="@string/download_resources_custom_url_hint"
|
||||
app:endIconMode="clear_text">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/edit_custom_map_server"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textUri"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
@@ -43,6 +43,7 @@
|
||||
<string name="pref_backup" translatable="false">Backup</string>
|
||||
<string name="pref_left_button" translatable="false">LeftButton</string>
|
||||
<string name="pref_power" translatable="false">pref_power</string>
|
||||
<string name="pref_custom_map_download_url" translatable="false">CustomMapDownloadUrl</string>
|
||||
|
||||
<string name="notification_ticker_ltr" translatable="false">%1$s: %2$s</string>
|
||||
<string name="notification_ticker_rtl" translatable="false">%2$s :%1$s</string>
|
||||
|
||||
@@ -966,4 +966,10 @@
|
||||
<string name="offline_explanation_title">Offline Maps</string>
|
||||
<string name="offline_explanation_text">A map needs to be downloaded to view and navigate the area.\nDownload maps for areas you want to travel.</string>
|
||||
<string name="list_description_empty">Edit the list to add a description</string>
|
||||
<!-- Custom Download URL -->
|
||||
<string name="download_resources_custom_url_title">Custom Map Server</string>
|
||||
<string name="download_resources_custom_url_message">Override the default map download server used for map downloads. Leave empty to use CoMaps default server.</string>
|
||||
<string name="download_resources_custom_url_hint">https://cdn-fi-1.comaps.app/</string>
|
||||
<string name="download_resources_custom_url_summary_none">Not set</string>
|
||||
<string name="download_resources_custom_url_error_scheme">Please enter a full URL starting with https:// and ending with /</string>
|
||||
</resources>
|
||||
|
||||
@@ -212,5 +212,11 @@
|
||||
android:defaultValue="true"
|
||||
android:widgetLayout="@layout/preference_switch"
|
||||
android:order="2"/>
|
||||
<Preference
|
||||
android:key="@string/pref_custom_map_download_url"
|
||||
android:title="@string/download_resources_custom_url_title"
|
||||
app:icon="@drawable/ic_cloud_download"
|
||||
android:order="3" />
|
||||
|
||||
</androidx.preference.PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
||||
|
||||
@@ -124,6 +124,7 @@ dependencies {
|
||||
implementation libs.androidx.lifecycle.process
|
||||
implementation libs.androidx.media
|
||||
implementation libs.androidx.recyclerview
|
||||
implementation libs.androidx.preference
|
||||
implementation libs.android.material
|
||||
|
||||
testImplementation libs.junit
|
||||
|
||||
@@ -42,12 +42,16 @@ using namespace std::placeholders;
|
||||
|
||||
namespace
|
||||
{
|
||||
std::unique_ptr<MapFilesDownloader> & LegacyDownloader()
|
||||
{
|
||||
static auto downloader = storage::GetDownloader();
|
||||
return downloader;
|
||||
}
|
||||
|
||||
static std::vector<platform::CountryFile> g_filesToDownload;
|
||||
static int g_totalDownloadedBytes;
|
||||
static int g_totalBytesToDownload;
|
||||
static std::shared_ptr<HttpRequest> g_currentRequest;
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C"
|
||||
@@ -152,11 +156,11 @@ JNIEXPORT jint JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_
|
||||
return ERR_NO_MORE_FILES;
|
||||
|
||||
/// @todo One downloader instance with cached servers. All this routine will be refactored some time.
|
||||
static auto downloader = storage::GetDownloader();
|
||||
auto & downloader = LegacyDownloader();
|
||||
storage::Storage const & storage = g_framework->GetStorage();
|
||||
downloader->SetDataVersion(storage.GetCurrentDataVersion());
|
||||
|
||||
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]()
|
||||
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener), &downloader]()
|
||||
{
|
||||
auto const & curFile = g_filesToDownload.back();
|
||||
auto const fileName = curFile.GetFileName(MapFileType::Map);
|
||||
@@ -177,4 +181,12 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_
|
||||
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
|
||||
g_currentRequest.reset();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_DownloadResourcesLegacyActivity_nativeResetMetaConfig(JNIEnv *,
|
||||
jclass)
|
||||
{
|
||||
auto & downloader = LegacyDownloader();
|
||||
if (downloader)
|
||||
downloader->ResetMetaConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1505,6 +1505,22 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeGet3dMode(JNIEnv
|
||||
env->SetBooleanField(result, buildingsField, buildings);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeSetCustomMapDownloadUrl(JNIEnv * env, jclass,
|
||||
jstring url)
|
||||
{
|
||||
std::string nativeUrl = jni::ToNativeString(env, url);
|
||||
GetPlatform().SetCustomMapServerUrl(nativeUrl);
|
||||
|
||||
if (g_framework)
|
||||
{
|
||||
frm()->GetStorage().ResetMapDownloadMetaConfig();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LINFO, ("nativeSetCustomMapDownloadUrl: framework not created yet, skipping ResetMapDownloadMetaConfig"));
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_Framework_nativeSetAutoZoomEnabled(JNIEnv * env, jclass,
|
||||
jboolean enabled)
|
||||
{
|
||||
|
||||
@@ -587,4 +587,11 @@ JNIEXPORT jstring JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeG
|
||||
storage::CountryId const & res = g_framework->GetPlacePageInfo().GetCountryId();
|
||||
return (res == storage::kInvalidCountryId ? nullptr : jni::ToJavaString(env, res));
|
||||
}
|
||||
|
||||
// static native boolean nativeIsMapTooOldToEdit(String countryId);
|
||||
JNIEXPORT jboolean JNICALL Java_app_organicmaps_sdk_downloader_MapManager_nativeIsMapTooOldToEdit(JNIEnv *env, jclass clazz,
|
||||
jstring country_id)
|
||||
{
|
||||
return GetStorage().IsMapTooOldToEdit(jni::ToNativeString(env, country_id));
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
@@ -27,4 +27,5 @@ public class DownloadResourcesLegacyActivity
|
||||
public static native int nativeGetBytesToDownload();
|
||||
public static native int nativeStartNextFileDownload(Listener listener);
|
||||
public static native void nativeCancelCurrentFile();
|
||||
public static native void nativeResetMetaConfig();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package app.organicmaps.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import app.organicmaps.sdk.api.ParsedRoutingData;
|
||||
import app.organicmaps.sdk.api.ParsedSearchRequest;
|
||||
import app.organicmaps.sdk.api.RequestType;
|
||||
@@ -23,6 +26,7 @@ import app.organicmaps.sdk.routing.RoutingRecommendationListener;
|
||||
import app.organicmaps.sdk.routing.TransitRouteInfo;
|
||||
import app.organicmaps.sdk.settings.SpeedCameraMode;
|
||||
import app.organicmaps.sdk.util.Constants;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
@@ -348,4 +352,20 @@ public class Framework
|
||||
|
||||
public static native void nativeMemoryWarning();
|
||||
public static native void nativeSaveRoute();
|
||||
public static native void nativeSetCustomMapDownloadUrl(String url);
|
||||
|
||||
public static void applyCustomMapDownloadUrl(@NonNull Context context, @Nullable String url)
|
||||
{
|
||||
nativeSetCustomMapDownloadUrl(normalizeServerUrl(url));
|
||||
// Reset the legacy downloader too (world/coasts).
|
||||
app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeResetMetaConfig();
|
||||
}
|
||||
|
||||
public static String normalizeServerUrl(@Nullable String url)
|
||||
{
|
||||
String out = url != null ? url.trim() : "";
|
||||
if (!out.isEmpty() && !out.endsWith("/"))
|
||||
out = out + "/";
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,13 @@ package app.organicmaps.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import app.organicmaps.sdk.bookmarks.data.BookmarkManager;
|
||||
import app.organicmaps.sdk.bookmarks.data.Icon;
|
||||
import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround;
|
||||
@@ -25,6 +28,7 @@ import app.organicmaps.sdk.util.SharedPropertiesUtils;
|
||||
import app.organicmaps.sdk.util.StorageUtils;
|
||||
import app.organicmaps.sdk.util.log.Logger;
|
||||
import app.organicmaps.sdk.util.log.LogsManager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class OrganicMaps implements DefaultLifecycleObserver
|
||||
@@ -167,6 +171,11 @@ public final class OrganicMaps implements DefaultLifecycleObserver
|
||||
/* isTablet */ false);
|
||||
Config.setStoragePath(writablePath);
|
||||
|
||||
// Use the same prefs as SettingsPrefsFragment
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
final String savedUrl = prefs.getString(mContext.getString(R.string.pref_custom_map_download_url), "");
|
||||
Framework.nativeSetCustomMapDownloadUrl(savedUrl.trim());
|
||||
|
||||
mPlatformInitialized = true;
|
||||
Logger.i(TAG, "Platform initialized");
|
||||
}
|
||||
|
||||
@@ -261,4 +261,9 @@ public final class MapManager
|
||||
* Returns country ID which the current PP object points to, or {@code null}.
|
||||
*/
|
||||
public static native @Nullable String nativeGetSelectedCountry();
|
||||
|
||||
/**
|
||||
* Returns true when the map exists and is too old for map editing.
|
||||
*/
|
||||
public static native boolean nativeIsMapTooOldToEdit(String countryId);
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
<string name="pref_file_name" translatable="false">OrganicMapsPrefs</string>
|
||||
<string name="pref_enable_logging" translatable="false">EnableLogging</string>
|
||||
<string name="pref_emulate_bad_external_storage" translatable="false">EmulateBadExternalStorage</string>
|
||||
<string name="pref_custom_map_download_url" translatable="false">CustomMapDownloadUrl</string>
|
||||
</resources>
|
||||
|
||||
23
data/styles/default/dark/symbols/shield-ro-dj-scaled.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg3604"
|
||||
width="41"
|
||||
height="35.213001"
|
||||
viewBox="0 0 820 704.26"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g3612"
|
||||
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
|
||||
<path
|
||||
id="path3660"
|
||||
style="fill:#999999;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="M 2787,4111 C 3245,3388 4042,2950 4898,2950 H 9398 V 13200 H 4898 c -856,0 -1653,-440 -2112,-1160 L 866.3,9013 C 504.2,8440 504.2,7710 866.3,7137 L 2786,4110" />
|
||||
<path
|
||||
d="M 9021,12820 H 4898 c -728,0 -1405,-370 -1795,-990 L 1183,8811 C 898.3,8362 898.3,7788 1183,7338 L 3103,4311 c 390,-613 1067,-986 1795,-986 h 4123 z"
|
||||
style="fill:#294c88;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
id="path3628" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1004 B |
23
data/styles/default/dark/symbols/shield-ro-dj.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg3604"
|
||||
width="34.599998"
|
||||
height="30.212999"
|
||||
viewBox="0 0 823.80951 719.35714"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g3612"
|
||||
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
|
||||
<path
|
||||
id="path3660"
|
||||
style="fill:#999999;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 2692.6554,4087.1907 c 458,-723 1255,-1161 2111,-1161 h 4500 V 13176.19 h -4500 c -856,0 -1653,-440 -2112,-1160 L 771.95535,8989.1907 c -362.1,-573 -362.1,-1303 0,-1876 l 1919.70005,-3027" />
|
||||
<path
|
||||
d="m 8926.6554,12796.19 h -4123 c -728,0 -1405,-370 -1795,-990 l -1920,-3018.9993 c -284.70005,-449 -284.70005,-1023 0,-1473 l 1920,-3027 c 390,-613 1067,-986 1795,-986 h 4123 z"
|
||||
style="fill:#294c88;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
id="path3628" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
20
data/styles/default/dark/symbols/shield-ro-dn-scaled.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg848"
|
||||
xml:space="preserve"
|
||||
width="38.514999"
|
||||
height="37"
|
||||
viewBox="0 0 770.29999 740"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<path
|
||||
id="path874"
|
||||
style="fill:#999999;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
|
||||
<path
|
||||
id="path872"
|
||||
style="fill:#9f1a17;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
20
data/styles/default/dark/symbols/shield-ro-dn.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg848"
|
||||
xml:space="preserve"
|
||||
width="32.514999"
|
||||
height="31"
|
||||
viewBox="0 0 774.16667 738.09526"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<path
|
||||
id="path874"
|
||||
style="fill:#999999;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
|
||||
<path
|
||||
id="path872"
|
||||
style="fill:#9f1a17;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
23
data/styles/default/light/symbols/shield-ro-dj-scaled.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg3604"
|
||||
width="41"
|
||||
height="35.213001"
|
||||
viewBox="0 0 820 704.26"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g3612"
|
||||
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
|
||||
<path
|
||||
id="path3660"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="M 2787,4111 C 3245,3388 4042,2950 4898,2950 H 9398 V 13200 H 4898 c -856,0 -1653,-440 -2112,-1160 L 866.3,9013 C 504.2,8440 504.2,7710 866.3,7137 L 2786,4110" />
|
||||
<path
|
||||
d="M 9021,12820 H 4898 c -728,0 -1405,-370 -1795,-990 L 1183,8811 C 898.3,8362 898.3,7788 1183,7338 L 3103,4311 c 390,-613 1067,-986 1795,-986 h 4123 z"
|
||||
style="fill:#1A5EC1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
id="path3628" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1004 B |
23
data/styles/default/light/symbols/shield-ro-dj.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg3604"
|
||||
width="34.599998"
|
||||
height="30.212999"
|
||||
viewBox="0 0 823.80951 719.35714"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g3612"
|
||||
transform="matrix(0,-0.08,-0.08,0,1056,751.84)">
|
||||
<path
|
||||
id="path3660"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 2692.6554,4087.1907 c 458,-723 1255,-1161 2111,-1161 h 4500 V 13176.19 h -4500 c -856,0 -1653,-440 -2112,-1160 L 771.95535,8989.1907 c -362.1,-573 -362.1,-1303 0,-1876 l 1919.70005,-3027" />
|
||||
<path
|
||||
d="m 8926.6554,12796.19 h -4123 c -728,0 -1405,-370 -1795,-990 l -1920,-3018.9993 c -284.70005,-449 -284.70005,-1023 0,-1473 l 1920,-3027 c 390,-613 1067,-986 1795,-986 h 4123 z"
|
||||
style="fill:#1A5EC1;fill-opacity:1;stroke-width:10.9979;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
id="path3628" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
20
data/styles/default/light/symbols/shield-ro-dn-scaled.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg848"
|
||||
xml:space="preserve"
|
||||
width="38.514999"
|
||||
height="37"
|
||||
viewBox="0 0 770.29999 740"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<path
|
||||
id="path874"
|
||||
style="fill:#ffffff;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
|
||||
<path
|
||||
id="path872"
|
||||
style="fill:#E63534;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;fill-opacity:1"
|
||||
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
20
data/styles/default/light/symbols/shield-ro-dn.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg848"
|
||||
xml:space="preserve"
|
||||
width="32.514999"
|
||||
height="31"
|
||||
viewBox="0 0 774.16667 738.09526"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
<path
|
||||
id="path874"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 612.9,7.16 -7.6,7.04 -7.7,6.64 -8,6.48 -8.2,6.24 -8.2,6 -8.6,5.68 -8.7,5.44 -8.8,5.12 -9,4.96 -9.1,4.64 -9.4,4.24 -9.4,4.08 -9.6,3.68 -9.6,3.52 -9.8,3.12 -9.8,2.8 -10,2.56 -10,2.24 -10,1.84 -10.3,1.6 -10.1,1.28 -10.3,0.88 -10.2,0.72 -10.3,0.32 H 380 l -10.2,-0.32 -10.3,-0.72 -10.2,-0.88 -10.2,-1.28 -10.1,-1.6 -10,-1.84 -10,-2.24 -10,-2.56 -9.9,-2.8 -9.7,-3.12 -9.7,-3.52 -9.5,-3.68 -9.5,-4.08 -9.3,-4.24 -9.2,-4.64 -8.9,-4.96 -8.5,-5.12 -9.6,-5.44 -8,-5.68 -8,-6 -8.8,-6.24 -8,-6.48 -7.2,-6.64 -8,-7.04 L 150,-0.04 0.4,150 l 4.8,5.5 5.6,5.7 4,5.9 4.8,6.1 4,6.4 4,6.4 4,6.6 4,6.7 2.4,6.8 3.2,7.1 2.4,7.1 2.4,7.2 2.4,7.3 1.6,7.3 1.6,7.5 0.8,7.6 1.6,7.5 v 7.5 l 0.8,7.6 v 7.6 l -0.8,7.6 -0.8,7.5 -0.8,7.5 -0.8,7.6 -1.6,7.3 -2.4,7.5 -1.6,7.2 -2.4,7.2 -3.2,7.1 -2.4,7 -3.2,6.9 -3.2,6.7 -4,6.6 c -36,58.7 -36.8,131.8 -3.2,191.5 34.4,59.6 96.8,96.5 165.6,96.5 l 1.6,-0.1 8.8,0.2 10.4,0.4 9.6,0.8 9.2,1.1 9.5,1.3 9.4,1.7 9.3,2 9.4,2.3 9.2,2.6 9.2,2.8 9,3.1 8.9,3.5 8.8,3.7 8.7,4 8.6,4.3 8.4,4.5 8.3,4.8 8.1,5.1 8,5.3 7.8,5.6 7.6,5.8 7.3,6.1 7.5,-6.1 7.6,-5.8 7.7,-5.6 7.9,-5.3 8.2,-5.1 8.3,-4.8 8.4,-4.5 8.5,-4.3 8.8,-4 8.8,-3.7 8.9,-3.5 9.1,-3.1 9.1,-2.8 9.2,-2.6 9.3,-2.3 9.4,-2 9.4,-1.7 9.4,-1.3 9.6,-1.1 9.6,-0.8 9.5,-0.4 10.1,-0.2 c 69.2,0 132.4,-36.9 166.1,-96.5 33.7,-59.6 32.7,-132.8 -2.5,-191.4 l -3.9,-6.6 -3.4,-6.7 -3.3,-6.9 -3,-7 -2.7,-7.1 -2.4,-7.2 -2.1,-7.2 -1.7,-7.5 -1.6,-7.3 -1.2,-7.6 -1,-7.5 -0.6,-7.5 -0.3,-7.6 v -7.6 l 0.2,-7.6 0.6,-7.5 0.9,-7.5 1.2,-7.6 1.5,-7.5 1.8,-7.3 2.1,-7.3 2.3,-7.2 2.6,-7.1 3,-7.1 3.2,-6.8 3.5,-6.7 3.8,-6.6 4,-6.4 4.2,-6.4 4.5,-6.1 4.8,-5.9 5,-5.7 5.2,-5.5 -150,-150.04 z" />
|
||||
<path
|
||||
id="path872"
|
||||
style="fill:#E63534;fill-opacity:1;stroke-width:0.9312;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
d="m 729.4,151.6 -4.8,6.6 -4.4,6.8 -4.3,7 -4,7 -3.7,7.2 -3.4,7.4 -3.2,7.5 -2.9,7.6 -2.6,7.7 -2.3,7.7 -2,7.9 -1.8,8 -1.4,8 -1.2,8 -0.8,8.1 -0.6,8.2 -0.2,8.1 v 8.1 l 0.4,8.1 0.7,8.1 0.9,8.1 1.2,8 1.6,8 1.7,8 2.3,7.8 2.4,7.8 2.7,7.6 2.9,7.6 3.2,7.4 3.6,7.3 3.8,7.2 4,7 c 29.6,49.5 30.5,111.1 2.2,161.2 -28.4,50.3 -81.6,81.4 -140,81.4 l -10.9,0.1 -10.3,0.5 -10.4,0.8 -10.3,1.1 -10.2,1.5 -10.2,1.8 -10.1,2.1 -10,2.4 -10,2.7 -10,3.1 -9.7,3.2 -9.8,3.7 -9.5,4 -9.4,4.3 -9.3,4.5 -9.1,4.8 -9.1,5.1 -8.8,5.5 -8.7,5.7 -8.5,5.9 -8.4,-5.9 -8.7,-5.7 -8.8,-5.5 -9,-5.1 -9.2,-4.8 -9.2,-4.5 -9.5,-4.3 -9.6,-4 -9.7,-3.7 -9.7,-3.2 -9.9,-3.1 -10,-2.7 -10.1,-2.4 -10.1,-2.1 -10.2,-1.8 -10.3,-1.5 -10.2,-1.1 -10.1,-0.8 -11.2,-0.5 H 190.8 C 132.4,639.2 78.8,608 50.8,557.8 22,507.6 22.8,446 53.2,396.5 l 4,-7 4,-7.2 2.4,-7.3 4,-7.4 3.2,-7.6 2.4,-7.6 2.4,-7.8 2.4,-7.8 1.6,-8 1.6,-8 1.6,-8 0.8,-8.1 0.8,-8.1 v -8.1 -8.1 -8.1 l -0.8,-8.2 -0.8,-8.1 -0.8,-8 -1.6,-8 -1.6,-8 -2.4,-7.9 -2.4,-7.7 -2.4,-7.7 -3.2,-7.6 -3.2,-7.5 -3.2,-7.4 -3.2,-7.2 -4,-7 -4.8,-7 -4.8,-6.8 -4.8,-6.6 110.4,-109.96 8,6.64 8,6.48 8.8,6.16 8.8,5.92 8.8,5.76 8,5.44 9.6,5.12 8.8,4.96 9.5,4.64 9.5,4.4 9.6,4.04 9.6,3.8 9.9,3.6 9.8,3.3 10,2.9 10,2.7 10.2,2.4 10.1,2.1 10.3,1.7 10.3,1.6 10.3,1.1 10.4,1 10.4,0.6 10.4,0.2 h 10.4 l 10.4,-0.2 10.4,-0.6 10.4,-1 10.3,-1.1 10.4,-1.6 10.2,-1.7 10.2,-2.1 10.1,-2.4 10.1,-2.7 10,-2.9 9.9,-3.3 9.8,-3.6 9.7,-3.8 9.6,-4.04 9.4,-4.4 9.3,-4.64 9.2,-4.96 9,-5.12 8.9,-5.44 8.6,-5.76 8.7,-5.92 8.3,-6.16 8.2,-6.48 8,-6.64 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -81,7 +81,7 @@ public:
|
||||
QPainter painter(device);
|
||||
painter.fillRect(QRectF(0.0, 0.0, device->width(), device->height()), Qt::white);
|
||||
|
||||
auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize, m_lang);
|
||||
auto const shapedText = m_mng->ShapeText(m_utf8, m_fontPixelSize);
|
||||
|
||||
std::cout << "Total width: " << shapedText.m_lineWidthInPixels << '\n';
|
||||
std::cout << "Max height: " << shapedText.m_maxLineHeightInPixels << '\n';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "drape/harfbuzz_shaping.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
#include "platform/preferred_languages.hpp"
|
||||
|
||||
#include "coding/hex.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
@@ -328,6 +329,9 @@ FreetypeError constexpr g_FT_Errors[] =
|
||||
TUniBlockIter m_lastUsedBlock;
|
||||
std::vector<std::unique_ptr<Font>> m_fonts;
|
||||
|
||||
std::string const lang = languages::GetCurrentOrig();
|
||||
hb_language_t const m_language = hb_language_from_string(lang.data(), static_cast<int>(lang.size()));
|
||||
|
||||
// Required to use std::string_view as a search key for std::unordered_map::find().
|
||||
struct StringHash : public std::hash<std::string_view>
|
||||
{
|
||||
@@ -563,21 +567,8 @@ FreetypeError constexpr g_FT_Errors[] =
|
||||
return m_impl->m_fonts[key.m_fontIndex]->GetGlyphImage(key.m_glyphId, pixelHeight, sdf);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
hb_language_t OrganicMapsLanguageToHarfbuzzLanguage(int8_t lang)
|
||||
{
|
||||
// TODO(AB): can langs be converted faster?
|
||||
auto const svLang = StringUtf8Multilang::GetLangByCode(lang);
|
||||
auto const hbLanguage = hb_language_from_string(svLang.data(), static_cast<int>(svLang.size()));
|
||||
if (hbLanguage == HB_LANGUAGE_INVALID)
|
||||
return hb_language_get_default();
|
||||
return hbLanguage;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// This method is NOT multithreading-safe.
|
||||
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang)
|
||||
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
static int const fontSize = fontPixelHeight;
|
||||
@@ -591,9 +582,6 @@ FreetypeError constexpr g_FT_Errors[] =
|
||||
|
||||
auto const [text, segments] = harfbuzz_shaping::GetTextSegments(utf8);
|
||||
|
||||
// TODO(AB): Optimize language conversion.
|
||||
hb_language_t const hbLanguage = OrganicMapsLanguageToHarfbuzzLanguage(lang);
|
||||
|
||||
text::TextMetrics allGlyphs;
|
||||
// For SplitText it's enough to know if the last visual (first logical) segment is RTL.
|
||||
allGlyphs.m_isRTL = segments.back().m_direction == HB_DIRECTION_RTL;
|
||||
@@ -609,7 +597,8 @@ FreetypeError constexpr g_FT_Errors[] =
|
||||
static_cast<int>(text.size()), substring.m_start, substring.m_length);
|
||||
hb_buffer_set_direction(m_impl->m_harfbuzzBuffer, substring.m_direction);
|
||||
hb_buffer_set_script(m_impl->m_harfbuzzBuffer, substring.m_script);
|
||||
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, hbLanguage);
|
||||
// TODO: This property is static, is it possible to set it only once?
|
||||
hb_buffer_set_language(m_impl->m_harfbuzzBuffer, m_impl->m_language);
|
||||
|
||||
auto u32CharacterIter{text.begin() + substring.m_start};
|
||||
auto const end{u32CharacterIter + substring.m_length};
|
||||
@@ -646,10 +635,4 @@ FreetypeError constexpr g_FT_Errors[] =
|
||||
|
||||
return allGlyphs;
|
||||
}
|
||||
|
||||
text::TextMetrics GlyphManager::ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang)
|
||||
{
|
||||
return ShapeText(utf8, fontPixelHeight, StringUtf8Multilang::GetLangIndex(lang));
|
||||
}
|
||||
|
||||
} // namespace dp
|
||||
|
||||
@@ -73,8 +73,7 @@ public:
|
||||
int GetFontIndex(strings::UniChar unicodePoint);
|
||||
int GetFontIndex(std::u16string_view sv);
|
||||
|
||||
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, int8_t lang);
|
||||
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight, char const * lang);
|
||||
text::TextMetrics ShapeText(std::string_view utf8, int fontPixelHeight);
|
||||
|
||||
GlyphImage GetGlyphImage(GlyphFontAndId key, int pixelHeight, bool sdf) const;
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
|
||||
m_maxGlypsCount = static_cast<uint32_t>(ceil(kGlyphAreaCoverage * textureSquare / averageGlyphSquare));
|
||||
|
||||
std::string_view constexpr kSpace{" "};
|
||||
m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels, "en").m_glyphs.front().m_key;
|
||||
m_spaceGlyph = m_glyphManager->ShapeText(kSpace, dp::kBaseFontSizePixels).m_glyphs.front().m_key;
|
||||
|
||||
LOG(LDEBUG, ("Glyphs texture size =", kGlyphsTextureSize, "with max glyphs count =", m_maxGlypsCount));
|
||||
|
||||
@@ -467,8 +467,7 @@ text::TextMetrics TextureManager::ShapeSingleTextLine(float fontPixelHeight, std
|
||||
// TODO(AB): Is this mutex too slow?
|
||||
std::lock_guard lock(m_calcGlyphsMutex);
|
||||
|
||||
// TODO(AB): Fix hard-coded lang.
|
||||
auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight, "en");
|
||||
auto textMetrics = m_glyphManager->ShapeText(utf8, fontPixelHeight);
|
||||
|
||||
auto const & glyphs = textMetrics.m_glyphs;
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ m2::PointF GetOffset(int offsetX, int offsetY)
|
||||
|
||||
bool IsSymbolRoadShield(ftypes::RoadShield const & shield)
|
||||
{
|
||||
return shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Green || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Blue || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Red || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Turkey || shield.m_type == ftypes::RoadShieldType::US_Interstate || shield.m_type == ftypes::RoadShieldType::US_Highway || shield.m_type == ftypes::RoadShieldType::Italy_Autostrada || shield.m_type == ftypes::RoadShieldType::Hungary_Green || shield.m_type == ftypes::RoadShieldType::Hungary_Blue;
|
||||
return shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Green || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Blue || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Red || shield.m_type == ftypes::RoadShieldType::Highway_Hexagon_Turkey || shield.m_type == ftypes::RoadShieldType::US_Interstate || shield.m_type == ftypes::RoadShieldType::US_Highway || shield.m_type == ftypes::RoadShieldType::Italy_Autostrada || shield.m_type == ftypes::RoadShieldType::Hungary_Green || shield.m_type == ftypes::RoadShieldType::Hungary_Blue || shield.m_type == ftypes::RoadShieldType::Romania_DN || shield.m_type == ftypes::RoadShieldType::Romania_DJ;
|
||||
}
|
||||
|
||||
std::string GetRoadShieldSymbolName(ftypes::RoadShield const & shield, double fontScale)
|
||||
@@ -221,6 +221,10 @@ std::string GetRoadShieldSymbolName(ftypes::RoadShield const & shield, double fo
|
||||
result = "shield-hungary-green";
|
||||
else if (shield.m_type == ftypes::RoadShieldType::Hungary_Blue)
|
||||
result = "shield-hungary-blue";
|
||||
else if (shield.m_type == ftypes::RoadShieldType::Romania_DN)
|
||||
result = "shield-ro-dn";
|
||||
else if (shield.m_type == ftypes::RoadShieldType::Romania_DJ)
|
||||
result = "shield-ro-dj";
|
||||
else
|
||||
ASSERT(false, ("This shield type doesn't support symbols:", shield.m_type));
|
||||
|
||||
@@ -327,7 +331,9 @@ dp::Color GetRoadShieldTextColor(dp::Color const & baseColor, ftypes::RoadShield
|
||||
{RoadShieldType::UK_Highway, kRoadShieldUKYellowTextColor},
|
||||
{RoadShieldType::Italy_Autostrada, kRoadShieldWhiteTextColor},
|
||||
{RoadShieldType::Hungary_Green, kRoadShieldWhiteTextColor},
|
||||
{RoadShieldType::Hungary_Blue, kRoadShieldWhiteTextColor}};
|
||||
{RoadShieldType::Hungary_Blue, kRoadShieldWhiteTextColor},
|
||||
{RoadShieldType::Romania_DN, kRoadShieldWhiteTextColor},
|
||||
{RoadShieldType::Romania_DJ, kRoadShieldWhiteTextColor}};
|
||||
|
||||
if (auto const * cl = kColors.Find(shield.m_type); cl)
|
||||
return df::GetColorConstant(*cl);
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace df
|
||||
{
|
||||
namespace
|
||||
{
|
||||
uint64_t constexpr kDoubleTapPauseMs = 250;
|
||||
uint64_t constexpr kLongTouchMs = 500;
|
||||
uint64_t constexpr kKineticDelayMs = 500;
|
||||
uint64_t constexpr kDoubleTapPauseMs = 160;
|
||||
uint64_t constexpr kLongTouchMs = 300;
|
||||
uint64_t constexpr kKineticDelayMs = 300;
|
||||
|
||||
float constexpr kForceTapThreshold = 0.75;
|
||||
|
||||
|
||||
@@ -514,9 +514,11 @@ public:
|
||||
: HighwayClassRoadShieldParser(baseRoadNumber, highwayClass,
|
||||
{{"A", HighwayClass::Motorway, RoadShieldType::Generic_Blue_Bordered},
|
||||
{"S", HighwayClass::Trunk, RoadShieldType::Generic_Blue_Bordered},
|
||||
{"B", HighwayClass::Primary, RoadShieldType::Generic_Blue},
|
||||
{"L", HighwayClass::Secondary, RoadShieldType::Generic_Pill_White_Bordered},
|
||||
{"L", HighwayClass::Tertiary, RoadShieldType::Generic_Pill_White_Bordered}})
|
||||
{"B", HighwayClass::Primary, RoadShieldType::Generic_Blue, false, true},
|
||||
{"B", HighwayClass::Trunk, RoadShieldType::Generic_Blue, false, true},
|
||||
{"P", HighwayClass::Primary, RoadShieldType::Generic_Pill_Red_Bordered, false, true},
|
||||
{"L", HighwayClass::Secondary, RoadShieldType::Generic_Pill_White_Bordered, false, true},
|
||||
{"L", HighwayClass::Tertiary, RoadShieldType::Generic_Pill_White_Bordered, false, true}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -554,9 +556,22 @@ class ItalyRoadShieldParser : public SimpleRoadShieldParser
|
||||
public:
|
||||
explicit ItalyRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Italy_Autostrada},
|
||||
{"SS", RoadShieldType::Generic_Blue},
|
||||
{"SR", RoadShieldType::Generic_Blue},
|
||||
{"SP", RoadShieldType::Generic_Blue}})
|
||||
{"T", RoadShieldType::Italy_Autostrada},
|
||||
{"RA", RoadShieldType::Generic_Green_Bordered},
|
||||
{"E", RoadShieldType::Generic_Green_Bordered},
|
||||
{"SS", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"SR", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"SP", RoadShieldType::Generic_Blue_Bordered}})
|
||||
{}
|
||||
};
|
||||
class AlbaniaRoadShieldParser : public SimpleRoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit AlbaniaRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Italy_Autostrada},
|
||||
{"SH", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"RR", RoadShieldType::Generic_Blue_Bordered},
|
||||
{"E", RoadShieldType::Generic_Green_Bordered}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -577,14 +592,6 @@ public:
|
||||
{}
|
||||
};
|
||||
|
||||
class LativaRoadShieldParser : public SimpleRoadShieldParser
|
||||
{
|
||||
public:
|
||||
explicit LativaRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Red}, {"P", RoadShieldType::Generic_Blue}})
|
||||
{}
|
||||
};
|
||||
|
||||
class MoldovaRoadShieldParser : public SimpleRoadShieldParser
|
||||
{
|
||||
public:
|
||||
@@ -599,7 +606,9 @@ public:
|
||||
explicit PortugalRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Blue},
|
||||
{"N", RoadShieldType::Generic_White_Bordered},
|
||||
{"IP", RoadShieldType::Generic_Red},
|
||||
{"EN", RoadShieldType::Generic_White_Bordered},
|
||||
{"IC", RoadShieldType::Generic_White_Bordered},
|
||||
{"R", RoadShieldType::Generic_Orange},
|
||||
{"EM", RoadShieldType::Generic_Orange},
|
||||
{"CM", RoadShieldType::Generic_Orange}})
|
||||
@@ -611,9 +620,10 @@ class RomaniaRoadShieldParser : public SimpleRoadShieldParser
|
||||
public:
|
||||
explicit RomaniaRoadShieldParser(std::string const & baseRoadNumber)
|
||||
: SimpleRoadShieldParser(baseRoadNumber, {{"A", RoadShieldType::Generic_Green},
|
||||
{"DN", RoadShieldType::Generic_Red},
|
||||
{"DJ", RoadShieldType::Generic_Blue},
|
||||
{"DC", RoadShieldType::Generic_Blue}})
|
||||
{"DN", RoadShieldType::Romania_DN, false, true},
|
||||
{"DJ", RoadShieldType::Romania_DJ, false, true},
|
||||
{"DC", RoadShieldType::Romania_DJ, false, true},
|
||||
{"DX", RoadShieldType::Romania_DJ, false, true}})
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -891,12 +901,14 @@ RoadShieldsSetT GetRoadShields(std::string const & mwmName, std::string const &
|
||||
return IrelandRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Italy")
|
||||
return ItalyRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Albania")
|
||||
return AlbaniaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Turkey")
|
||||
return TurkeyRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Hungary")
|
||||
return HungaryRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Lativa")
|
||||
return LativaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Latvia")
|
||||
return LatviaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Moldova")
|
||||
return MoldovaRoadShieldParser(roadNumber).GetRoadShields();
|
||||
if (mwmName == "Portugal")
|
||||
@@ -997,6 +1009,8 @@ std::string DebugPrint(RoadShieldType shieldType)
|
||||
case RoadShieldType::Italy_Autostrada: return "Italy autostrada";
|
||||
case RoadShieldType::Hungary_Green: return "hungary green";
|
||||
case RoadShieldType::Hungary_Blue: return "hungary blue";
|
||||
case RoadShieldType::Romania_DN: return "romania dn";
|
||||
case RoadShieldType::Romania_DJ: return "romania dj";
|
||||
case RoadShieldType::Hidden: return "hidden";
|
||||
case RoadShieldType::Count: CHECK(false, ("RoadShieldType::Count is not to be used as a type"));
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ enum class RoadShieldType
|
||||
Italy_Autostrada,
|
||||
Hungary_Green,
|
||||
Hungary_Blue,
|
||||
Romania_DN,
|
||||
Romania_DJ,
|
||||
Hidden,
|
||||
Count
|
||||
};
|
||||
|
||||
@@ -150,6 +150,17 @@ std::string Platform::ReadPathForFile(std::string const & file, std::string sear
|
||||
"\nr: ", m_resourcesDir, "\ns: ", m_settingsDir));
|
||||
}
|
||||
|
||||
void Platform::SetCustomMapServerUrl(std::string & url)
|
||||
{
|
||||
strings::Trim(url);
|
||||
m_customMapServerUrl = std::move(url);
|
||||
}
|
||||
|
||||
std::string const & Platform::CustomMapServerUrl() const
|
||||
{
|
||||
return m_customMapServerUrl;
|
||||
}
|
||||
|
||||
std::string Platform::MetaServerUrl() const
|
||||
{
|
||||
return METASERVER_URL;
|
||||
|
||||
@@ -268,6 +268,10 @@ public:
|
||||
/// @return integer version in yyMMdd format.
|
||||
int32_t IntVersion() const;
|
||||
|
||||
/// Set custom map server url to allow user-defined download servers
|
||||
void SetCustomMapServerUrl(std::string & url);
|
||||
std::string const & CustomMapServerUrl() const;
|
||||
|
||||
/// @return url for clients to download maps
|
||||
std::string MetaServerUrl() const;
|
||||
|
||||
@@ -339,6 +343,8 @@ private:
|
||||
void ShutdownThreads();
|
||||
|
||||
void GetSystemFontNames(FilesList & res) const;
|
||||
|
||||
std::string m_customMapServerUrl;
|
||||
};
|
||||
|
||||
std::string DebugPrint(Platform::EError err);
|
||||
|
||||
@@ -156,6 +156,18 @@ std::string GetAcceptLanguage()
|
||||
MetaConfig MapFilesDownloader::LoadMetaConfig()
|
||||
{
|
||||
Platform & pl = GetPlatform();
|
||||
|
||||
// If user sets a custom download server, skip metaserver entirely.
|
||||
std::string const customServer = pl.CustomMapServerUrl();
|
||||
if (!customServer.empty())
|
||||
{
|
||||
LOG(LINFO, ("Using custom map server URL:", customServer));
|
||||
|
||||
MetaConfig metaConfig;
|
||||
metaConfig.m_serversList = {customServer};
|
||||
return metaConfig;
|
||||
}
|
||||
|
||||
std::string const metaServerUrl = pl.MetaServerUrl();
|
||||
std::string httpResult;
|
||||
|
||||
@@ -170,7 +182,7 @@ MetaConfig MapFilesDownloader::LoadMetaConfig()
|
||||
request.RunHttpRequest(httpResult);
|
||||
}
|
||||
|
||||
std::optional<MetaConfig> metaConfig = downloader::ParseMetaConfig(httpResult);
|
||||
auto metaConfig = downloader::ParseMetaConfig(httpResult);
|
||||
if (!metaConfig)
|
||||
{
|
||||
metaConfig = downloader::ParseMetaConfig(pl.DefaultUrlsJSON());
|
||||
@@ -181,6 +193,7 @@ MetaConfig MapFilesDownloader::LoadMetaConfig()
|
||||
{
|
||||
LOG(LINFO, ("Got servers list:", metaConfig->m_serversList));
|
||||
}
|
||||
|
||||
CHECK(!metaConfig->m_serversList.empty(), ());
|
||||
return *metaConfig;
|
||||
}
|
||||
@@ -190,4 +203,10 @@ void MapFilesDownloader::GetMetaConfig(MetaConfigCallback const & callback)
|
||||
callback(LoadMetaConfig());
|
||||
}
|
||||
|
||||
void MapFilesDownloader::ResetMetaConfig()
|
||||
{
|
||||
m_serversList.clear();
|
||||
m_isMetaConfigRequested = false;
|
||||
}
|
||||
|
||||
} // namespace storage
|
||||
|
||||
@@ -66,6 +66,9 @@ public:
|
||||
void SetDownloadingPolicy(DownloadingPolicy * policy);
|
||||
void SetDataVersion(int64_t version) { m_dataVersion = version; }
|
||||
|
||||
/// Reset after changes, e.g. map download URL.
|
||||
void ResetMetaConfig();
|
||||
|
||||
/// @name Legacy functions for Android resources downloading routine (initial World download).
|
||||
/// @{
|
||||
void EnsureMetaConfigReady(std::function<void()> && callback);
|
||||
|
||||
@@ -1252,15 +1252,32 @@ bool Storage::IsAllowedToEditVersion(CountryId const & countryId) const
|
||||
case Status::OnDiskOutOfDate:
|
||||
{
|
||||
auto const localFile = GetLatestLocalFile(countryId);
|
||||
return IsAllowedToEditFile(localFile);
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Storage::IsMapTooOldToEdit(CountryId const & countryId) const
|
||||
{
|
||||
auto const status = CountryStatusEx(countryId);
|
||||
if (status == Status::OnDiskOutOfDate)
|
||||
{
|
||||
LocalFilePtr const localFile = GetLatestLocalFile(countryId);
|
||||
return !IsAllowedToEditFile(localFile);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::IsAllowedToEditFile(LocalFilePtr const & localFile) const
|
||||
{
|
||||
ASSERT(localFile, ("Local file shouldn't be nullptr."));
|
||||
auto const currentVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(m_currentVersion));
|
||||
auto const localVersionTime = base::YYMMDDToSecondsSinceEpoch(static_cast<uint32_t>(localFile->GetVersion()));
|
||||
return currentVersionTime - localVersionTime < kMaxSecondsTillLastVersionUpdate &&
|
||||
base::SecondsSinceEpoch() - localVersionTime < kMaxSecondsTillNoEdits;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t Storage::GetVersion(CountryId const & countryId) const
|
||||
{
|
||||
|
||||
@@ -383,6 +383,9 @@ public:
|
||||
/// \brief Returns true if the version of countryId can be used to update maps.
|
||||
bool IsAllowedToEditVersion(CountryId const & countryId) const;
|
||||
|
||||
/// \brief Returns true when the map exists and is too old for map editing.
|
||||
bool IsMapTooOldToEdit(CountryId const & countryId) const;
|
||||
|
||||
/// Returns version of downloaded mwm or zero.
|
||||
int64_t GetVersion(CountryId const & countryId) const;
|
||||
|
||||
@@ -582,6 +585,12 @@ public:
|
||||
|
||||
void RestoreDownloadQueue();
|
||||
|
||||
void ResetMapDownloadMetaConfig()
|
||||
{
|
||||
if (m_downloader)
|
||||
m_downloader->ResetMetaConfig();
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnFinishDownloading();
|
||||
|
||||
@@ -619,6 +628,8 @@ private:
|
||||
// Returns a path to a place on disk downloader can use for downloaded files.
|
||||
std::string GetFileDownloadPath(CountryId const & countryId, MapFileType file) const;
|
||||
|
||||
bool IsAllowedToEditFile(LocalFilePtr const & localFile) const;
|
||||
|
||||
/// Fast version, doesn't check if country is out of date
|
||||
Status CountryStatus(CountryId const & countryId) const;
|
||||
|
||||
|
||||