diff options
Diffstat (limited to 'platform')
8 files changed, 167 insertions, 12 deletions
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index c2baec48a8..813d8b45ea 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -4,6 +4,9 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ## master +### Features + - Add fallback support to local ideograph font families [#15255](https://github.com/mapbox/mapbox-gl-native/pull/15255) + ### Bug fixes - Fixed an issue where it was possible to set the map’s content insets then tilt the map enough to see the horizon, causing performance issues [#15195](https://github.com/mapbox/mapbox-gl-native/pull/15195) - Allow loading of a map without a Style URI or Style JSON [#15293](https://github.com/mapbox/mapbox-gl-native/pull/15293) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index 2c906e7203..d490fd3900 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -44,6 +44,11 @@ public class MapboxConstants { public static final boolean DEFAULT_MANAGE_SKU_TOKEN = true; /** + * Default value for font fallback for local ideograph fonts + */ + public static final String DEFAULT_FONT = "sans-serif"; + + /** * Unmeasured state */ public static final float UNMEASURED = -1f; 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 a394b97124..f922117dd0 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 @@ -19,6 +19,7 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.utils.BitmapUtils; +import com.mapbox.mapboxsdk.utils.FontUtils; import java.util.Arrays; @@ -70,7 +71,6 @@ public class MapboxMapOptions implements Parcelable { private boolean prefetchesTiles = true; private boolean zMediaOverlay = false; private String localIdeographFontFamily; - private String apiBaseUri; private boolean textureMode; @@ -250,7 +250,7 @@ public class MapboxMapOptions implements Parcelable { String localIdeographFontFamily = typedArray.getString(R.styleable.mapbox_MapView_mapbox_localIdeographFontFamily); if (localIdeographFontFamily == null) { - localIdeographFontFamily = "sans-serif"; + localIdeographFontFamily = MapboxConstants.DEFAULT_FONT; } mapboxMapOptions.localIdeographFontFamily(localIdeographFontFamily); @@ -637,14 +637,33 @@ public class MapboxMapOptions implements Parcelable { * <p> * The font family argument is passed to {@link android.graphics.Typeface#create(String, int)}. * Default system fonts are defined in '/system/etc/fonts.xml' - * Default font for local ideograph font family is "sans-serif". + * Default font for local ideograph font family is {@link MapboxConstants#DEFAULT_FONT}. * * @param fontFamily font family for local ideograph generation. * @return This */ @NonNull public MapboxMapOptions localIdeographFontFamily(String fontFamily) { - this.localIdeographFontFamily = fontFamily; + this.localIdeographFontFamily = FontUtils.extractValidFont(fontFamily); + return this; + } + + /** + * Set a font family from range of font families for generating glyphs locally for ideographs in the + * 'CJK Unified Ideographs' and 'Hangul Syllables' ranges. The first matching font + * will be selected. If no valid font found, it defaults to {@link MapboxConstants#DEFAULT_FONT}. + * <p> + * The font families are checked against the default system fonts defined in + * '/system/etc/fonts.xml' Default font for local ideograph font family is + * {@link MapboxConstants#DEFAULT_FONT}. + * </p> + * + * @param fontFamilies an array of font families for local ideograph generation. + * @return This + */ + @NonNull + public MapboxMapOptions localIdeographFontFamily(String... fontFamilies) { + this.localIdeographFontFamily = FontUtils.extractValidFont(fontFamilies); return this; } @@ -942,7 +961,7 @@ 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 "sans-serif". + * Default font for local ideograph font family is {@link MapboxConstants#DEFAULT_FONT}. * * @return Local ideograph font family name. */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java index e8e38c4f4e..4c70d13b17 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java @@ -18,17 +18,20 @@ import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; + import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.attribution.AttributionLayout; import com.mapbox.mapboxsdk.attribution.AttributionMeasure; import com.mapbox.mapboxsdk.attribution.AttributionParser; import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.log.Logger; import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.mapboxsdk.maps.TelemetryDefinition; import com.mapbox.mapboxsdk.storage.FileSource; +import com.mapbox.mapboxsdk.utils.FontUtils; import com.mapbox.mapboxsdk.utils.ThreadUtils; /** @@ -98,7 +101,7 @@ public class MapSnapshotter { private LatLngBounds region; private CameraPosition cameraPosition; private boolean showLogo = true; - private String localIdeographFontFamily = "sans-serif"; + private String localIdeographFontFamily = MapboxConstants.DEFAULT_FONT; private String apiBaseUrl; /** @@ -182,14 +185,31 @@ public class MapSnapshotter { * <p> * The font family argument is passed to {@link android.graphics.Typeface#create(String, int)}. * Default system fonts are defined in '/system/etc/fonts.xml' - * Default font for local ideograph font family is "sans-serif". - * + * Default font for local ideograph font family is {@link MapboxConstants#DEFAULT_FONT}. + * </p> * @param fontFamily font family for local ideograph generation. * @return the mutated {@link Options} */ @NonNull public Options withLocalIdeographFontFamily(String fontFamily) { - this.localIdeographFontFamily = fontFamily; + this.localIdeographFontFamily = FontUtils.extractValidFont(fontFamily); + return this; + } + + /** + * Set a font family from range of font families for generating glyphs locally for ideographs in the + * 'CJK Unified Ideographs' and 'Hangul Syllables' ranges. + * <p> + * The font families are checked against the default system fonts defined in + * '/system/etc/fonts.xml'. Default font for local ideograph font family is + * {@link MapboxConstants#DEFAULT_FONT}. + * </p> + * @param fontFamilies font families for local ideograph generation. + * @return the mutated {@link Options} + */ + @NonNull + public Options withLocalIdeographFontFamily(String... fontFamilies) { + this.localIdeographFontFamily = FontUtils.extractValidFont(fontFamilies); return this; } @@ -274,7 +294,7 @@ public class MapSnapshotter { /** * @return the font family used for locally generating ideographs, - * Default font for local ideograph font family is "sans-serif". + * Default font for local ideograph font family is {@link MapboxConstants#DEFAULT_FONT}. */ public String getLocalIdeographFontFamily() { return localIdeographFontFamily; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/FontUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/FontUtils.java new file mode 100644 index 0000000000..09064ee168 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/FontUtils.java @@ -0,0 +1,64 @@ +package com.mapbox.mapboxsdk.utils; + +import android.graphics.Typeface; + +import com.mapbox.mapboxsdk.MapStrictMode; +import com.mapbox.mapboxsdk.log.Logger; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.mapbox.mapboxsdk.constants.MapboxConstants.DEFAULT_FONT; + +/** + * Utility class to select a font from a range of font names based on the availability of fonts on the device. + */ +public class FontUtils { + + private static final String TAG = "Mbgl-FontUtils"; + + private FontUtils() { + // no instance + } + + /** + * Select a font from a range of font names to match the availability of fonts on the device. + * + * @param fontNames the range of font names to select from + * @return the selected fon + */ + public static String extractValidFont(String... fontNames) { + if (fontNames == null) { + return null; + } + + List<String> validFonts = getAvailableFonts(); + for (String fontName : fontNames) { + if (validFonts.contains(fontName)) { + return fontName; + } + } + + Logger.i(TAG, String.format( + "Couldn't map font family for local ideograph, using %s instead", DEFAULT_FONT) + ); + return DEFAULT_FONT; + } + + private static List<String> getAvailableFonts() { + List<String> fonts = new ArrayList<>(); + try { + Typeface typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL); + Field f = Typeface.class.getDeclaredField("sSystemFontMap"); + f.setAccessible(true); + Map<String, Typeface> fontMap = (Map<String, Typeface>) f.get(typeface); + fonts.addAll(fontMap.keySet()); + } catch (Exception exception) { + Logger.e(TAG,"Couldn't load fonts from Typeface", exception); + MapStrictMode.strictModeViolation("Couldn't load fonts from Typeface", exception); + } + return fonts; + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java index 11035c050f..6978afcf1f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java @@ -180,7 +180,7 @@ public class MapboxMapOptionsTest { @Test public void testLocalIdeographFontFamily_enabledByDefault() { MapboxMapOptions options = MapboxMapOptions.createFromAttributes(RuntimeEnvironment.application, null); - assertEquals("sans-serif", options.getLocalIdeographFontFamily()); + assertEquals(MapboxConstants.DEFAULT_FONT, options.getLocalIdeographFontFamily()); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.java new file mode 100644 index 0000000000..694215d16f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/utils/FontUtilsTest.java @@ -0,0 +1,43 @@ +package com.mapbox.mapboxsdk.utils; + +import android.support.test.runner.AndroidJUnit4; + +import com.mapbox.mapboxsdk.constants.MapboxConstants; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +@RunWith(AndroidJUnit4.class) +public class FontUtilsTest { + + @Test + public void testExtractedFontShouldMatchDefault() { + String[] fonts = new String[] {"foo", "bar"}; + String actual = FontUtils.extractValidFont(fonts); + assertEquals("Selected font should match", MapboxConstants.DEFAULT_FONT, actual); + } + + @Test + public void testExtractedFontShouldMatchMonospace() { + String expected = "monospace"; + String[] fonts = new String[] {"foo", expected}; + String actual = FontUtils.extractValidFont(fonts); + assertEquals("Selected font should match", expected, actual); + } + + @Test + public void testExtractedFontArrayShouldBeNull() { + String[] fonts = null; + String actual = FontUtils.extractValidFont(fonts); + assertNull(actual); + } + + @Test + public void testExtractedFontShouldBeNull() { + String actual = FontUtils.extractValidFont(null); + assertNull(actual); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java index 74fdf3d751..59c708266e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterActivity.java @@ -7,6 +7,7 @@ import android.widget.GridLayout; import android.widget.ImageView; import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -68,7 +69,7 @@ public class MapSnapshotterActivity extends AppCompatActivity { // Optionally the style .withStyle((column + row) % 2 == 0 ? Style.MAPBOX_STREETS : Style.DARK) - .withLocalIdeographFontFamily("sans-serif"); + .withLocalIdeographFontFamily(MapboxConstants.DEFAULT_FONT); // Optionally the visible region if (row % 2 == 0) { |