[android] add fallback support to local ideograph font families, allow setting a collection of fonts
This commit is contained in:
@@ -43,6 +43,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
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user