From 68c0125df23336f7e59b431a564cc5ed7e3b8351 Mon Sep 17 00:00:00 2001 From: tobrun Date: Mon, 26 Aug 2019 16:34:49 +0200 Subject: [android] add font array attribute configuration for local ideograph font, add enable flag attribute configuration --- platform/android/CHANGELOG.md | 11 ++- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 81 +++++++++++++++-- .../src/main/res/values/attrs.xml | 2 + .../mapboxsdk/maps/MapboxMapOptionsAttrsTest.kt | 101 +++++++++++++++++++++ .../main/res/layout/activity_camera_position.xml | 1 + .../main/res/layout/activity_gesture_detector.xml | 1 + .../src/main/res/values/arrays.xml | 5 + 7 files changed, 190 insertions(+), 12 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsAttrsTest.kt diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index cde67cbf07..61ff97e10e 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -6,12 +6,17 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ### Features - Introduce `clusterProperties` option for aggregated cluster properties. [#15425](https://github.com/mapbox/mapbox-gl-native/pull/15425) -### Bug fixes -- Fixed a rendering issue that non-SDF icon would be treated as SDF icon if they are in the same layer. [#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456) +## 8.3.0 - August 28, 2019 +[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.0-beta.1...android-v8.3.0) since [Mapbox Maps SDK for Android v8.3.0-beta.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.0-beta.1): -## 8.3.0 This release changes how offline tile requests are billed — they are now billed on a pay-as-you-go basis and all developers are able raise the offline tile limit for their users. Offline requests were previously exempt from monthly active user (MAU) billing and increasing the offline per-user tile limit to more than 6,000 tiles required the purchase of an enterprise license. By upgrading to this release, you are opting into the changes outlined in [this blog post](https://blog.mapbox.com/offline-maps-for-all-bb0fc51827be) and [#15380](https://github.com/mapbox/mapbox-gl-native/pull/15380). +### Features + - Allow ability to pass a string array resource into `localIdeographFontFamily` for enabling/disabling the feature and specifying fallback fonts. [#15488](https://github.com/mapbox/mapbox-gl-native/pull/15488) + +### Bug fixes + - Fixed a rendering issue caused by all icons being treated as SDFs if an SDF and non-SDF icon were in the same layer. [#15456](https://github.com/mapbox/mapbox-gl-native/pull/15456) + ## 8.2.2 - August 23, 2019 [Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.2.1...android-v8.2.2) since [Mapbox Maps SDK for Android v8.2.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.2.1): diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java index f922117dd0..6cd3271d12 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java @@ -10,6 +10,7 @@ import android.os.Parcelable; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.v4.content.res.ResourcesCompat; import android.text.TextUtils; import android.util.AttributeSet; @@ -70,7 +71,11 @@ public class MapboxMapOptions implements Parcelable { private boolean prefetchesTiles = true; private boolean zMediaOverlay = false; + + private boolean localIdeographFontFamilyEnabled = true; private String localIdeographFontFamily; + private String[] localIdeographFontFamilies; + private String apiBaseUri; private boolean textureMode; @@ -130,7 +135,9 @@ public class MapboxMapOptions implements Parcelable { translucentTextureSurface = in.readByte() != 0; prefetchesTiles = in.readByte() != 0; zMediaOverlay = in.readByte() != 0; + localIdeographFontFamilyEnabled = in.readByte() != 0; localIdeographFontFamily = in.readString(); + localIdeographFontFamilies = in.createStringArray(); pixelRatio = in.readFloat(); foregroundLoadColor = in.readInt(); crossSourceCollisions = in.readByte() != 0; @@ -156,9 +163,15 @@ public class MapboxMapOptions implements Parcelable { */ @NonNull public static MapboxMapOptions createFromAttributes(@NonNull Context context, @Nullable AttributeSet attrs) { - MapboxMapOptions mapboxMapOptions = new MapboxMapOptions(); - float pxlRatio = context.getResources().getDisplayMetrics().density; TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.mapbox_MapView, 0, 0); + return createFromAttributes(new MapboxMapOptions(), context, typedArray); + } + + @VisibleForTesting + static MapboxMapOptions createFromAttributes(@NonNull MapboxMapOptions mapboxMapOptions, + @NonNull Context context, + @Nullable TypedArray typedArray) { + float pxlRatio = context.getResources().getDisplayMetrics().density; try { mapboxMapOptions.camera(new CameraPosition.Builder(typedArray).build()); @@ -247,12 +260,24 @@ public class MapboxMapOptions implements Parcelable { mapboxMapOptions.renderSurfaceOnTop( typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_enableZMediaOverlay, false)); - String localIdeographFontFamily = - typedArray.getString(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamily); - if (localIdeographFontFamily == null) { - localIdeographFontFamily = MapboxConstants.DEFAULT_FONT; + mapboxMapOptions.localIdeographFontFamilyEnabled = + typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_localIdeographEnabled, true); + + int localIdeographFontFamiliesResId = + typedArray.getResourceId(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamilies, 0); + if (localIdeographFontFamiliesResId != 0) { + String[] localIdeographFontFamilies = + context.getResources().getStringArray(localIdeographFontFamiliesResId); + mapboxMapOptions.localIdeographFontFamily(localIdeographFontFamilies); + } else { + // did user provide xml font string? + String localIdeographFontFamily = + typedArray.getString(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamily); + if (localIdeographFontFamily == null) { + localIdeographFontFamily = MapboxConstants.DEFAULT_FONT; + } + mapboxMapOptions.localIdeographFontFamily(localIdeographFontFamily); } - mapboxMapOptions.localIdeographFontFamily(localIdeographFontFamily); mapboxMapOptions.pixelRatio( typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_pixelRatio, 0)); @@ -631,6 +656,18 @@ public class MapboxMapOptions implements Parcelable { return this; } + /** + * Enable local ideograph font family, defaults to true. + * + * @param enabled true to enable, false to disable + * @return This + */ + @NonNull + public MapboxMapOptions localIdeographFontFamilyEnabled(boolean enabled) { + this.localIdeographFontFamilyEnabled = enabled; + return this; + } + /** * Set the font family for generating glyphs locally for ideographs in the 'CJK Unified Ideographs' * and 'Hangul Syllables' ranges. @@ -944,6 +981,11 @@ public class MapboxMapOptions implements Parcelable { return textureMode; } + /** + * Returns true if TextureView supports a translucent surface + * + * @return True if translucent surface is active + */ public boolean getTranslucentTextureSurface() { return translucentTextureSurface; } @@ -962,11 +1004,22 @@ public class MapboxMapOptions implements Parcelable { * Returns the font-family for locally overriding generation of glyphs in the * 'CJK Unified Ideographs' and 'Hangul Syllables' ranges. * Default font for local ideograph font family is {@link MapboxConstants#DEFAULT_FONT}. + * Returns null if local ideograph font families are disabled. * * @return Local ideograph font family name. */ + @Nullable public String getLocalIdeographFontFamily() { - return localIdeographFontFamily; + return localIdeographFontFamilyEnabled ? localIdeographFontFamily : null; + } + + /** + * Returns true if local ideograph font family is enabled, defaults to true. + * + * @return True if local ideograph font family is enabled + */ + public boolean isLocalIdeographFontFamilyEnabled() { + return localIdeographFontFamilyEnabled; } /** @@ -1029,7 +1082,9 @@ public class MapboxMapOptions implements Parcelable { dest.writeByte((byte) (translucentTextureSurface ? 1 : 0)); dest.writeByte((byte) (prefetchesTiles ? 1 : 0)); dest.writeByte((byte) (zMediaOverlay ? 1 : 0)); + dest.writeByte((byte) (localIdeographFontFamilyEnabled ? 1 : 0)); dest.writeString(localIdeographFontFamily); + dest.writeStringArray(localIdeographFontFamilies); dest.writeFloat(pixelRatio); dest.writeInt(foregroundLoadColor); dest.writeByte((byte) (crossSourceCollisions ? 1 : 0)); @@ -1114,7 +1169,6 @@ public class MapboxMapOptions implements Parcelable { if (!Arrays.equals(attributionMargins, options.attributionMargins)) { return false; } - if (apiBaseUri != null ? !apiBaseUri.equals(options.apiBaseUri) : options.apiBaseUri != null) { return false; } @@ -1124,9 +1178,16 @@ public class MapboxMapOptions implements Parcelable { if (zMediaOverlay != options.zMediaOverlay) { return false; } + if (localIdeographFontFamilyEnabled != options.localIdeographFontFamilyEnabled) { + return false; + } if (!localIdeographFontFamily.equals(options.localIdeographFontFamily)) { return false; } + if (!Arrays.equals(localIdeographFontFamilies, options.localIdeographFontFamilies)) { + return false; + } + if (pixelRatio != options.pixelRatio) { return false; } @@ -1171,7 +1232,9 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + (translucentTextureSurface ? 1 : 0); result = 31 * result + (prefetchesTiles ? 1 : 0); result = 31 * result + (zMediaOverlay ? 1 : 0); + result = 31 * result + (localIdeographFontFamilyEnabled ? 1 : 0); result = 31 * result + (localIdeographFontFamily != null ? localIdeographFontFamily.hashCode() : 0); + result = 31 * result + Arrays.hashCode(localIdeographFontFamilies); result = 31 * result + (int) pixelRatio; result = 31 * result + (crossSourceCollisions ? 1 : 0); return result; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml index 3e7124a414..ff8a32ac64 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml @@ -7,7 +7,9 @@ + + diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsAttrsTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsAttrsTest.kt new file mode 100644 index 0000000000..ee8024257f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsAttrsTest.kt @@ -0,0 +1,101 @@ +package com.mapbox.mapboxsdk.maps + +import android.content.Context +import android.content.res.Resources +import android.content.res.TypedArray +import com.mapbox.mapboxsdk.R +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.verify +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class MapboxMapOptionsAttrsTest { + + @RelaxedMockK + private lateinit var options: MapboxMapOptions + + @RelaxedMockK + private lateinit var typedArray: TypedArray + + @RelaxedMockK + private lateinit var context: Context + + @RelaxedMockK + private lateinit var resources: Resources + + @Before + fun setUp() { + MockKAnnotations.init(this) + every { + context.resources + }.returns(resources) + } + + @Test + fun enabledLocalIdeographFontFamily() { + mockEnableLocalIdeograph(enabled = true) + + val options = MapboxMapOptions.createFromAttributes(options, context, typedArray) + + verify(exactly = 1) { + options.localIdeographFontFamily(any()) + } + } + + @Test + fun localIdeographFontFamily() { + mockEnableLocalIdeograph(enabled = true) + + val font = "foo" + mockLocalIdeographString(font) + + val options = MapboxMapOptions.createFromAttributes(options, context, typedArray) + + verify(exactly = 1) { + options.localIdeographFontFamily(font) + } + } + + @Test + fun localIdeographFontFamilies() { + mockEnableLocalIdeograph(enabled = true) + + val fonts = arrayOf("foo", "bar") + mockLocalIdeographStringArray(fonts) + + val options = MapboxMapOptions.createFromAttributes(options, context, typedArray) + + verify(exactly = 1) { + options.localIdeographFontFamily(*fonts) + } + } + + private fun mockEnableLocalIdeograph(enabled: Boolean) { + every { + typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_localIdeographEnabled, true) + }.returns(enabled) + } + + private fun mockLocalIdeographString(font: String) { + every { + typedArray.getString(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamily) + }.returns(font) + } + + private fun mockLocalIdeographStringArray(fonts: Array) { + val resId = 9000 + + every { + typedArray.getResourceId(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamilies, 0) + }.returns(resId) + + every { + resources.getStringArray(resId) + }.returns(fonts) + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml index 28bdaf7b2a..9b57e18a7a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml @@ -18,6 +18,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" + app:mapbox_localIdeographFontFamilies="@array/array_local_ideograph_family_test" app:mapbox_uiAttributionTintColor="@color/redAccent"/> diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/arrays.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/arrays.xml index 4b7ded8e3a..ad9f88a46e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/arrays.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/arrays.xml @@ -7,4 +7,9 @@ 1000 10000 + + foo + monospace + bar + \ No newline at end of file -- cgit v1.2.1