mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 00:15:32 +00:00
Merge pull request #16188 from keymanapp/fix/android/16187_font
fix(android): differentiate between fontPath and fontUrl in Keyman Engine for Android
This commit is contained in:
commit
fcf8988910
6 changed files with 112 additions and 87 deletions
|
|
@ -1,9 +1,10 @@
|
|||
/**
|
||||
* Copyright (C) 2017 SIL International. All rights reserved.
|
||||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
|
||||
package com.tavultesoft.kmapro;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
|
@ -386,7 +387,7 @@ public class WebBrowserActivity extends BaseActivity {
|
|||
super.onResume();
|
||||
if (webView != null) {
|
||||
if (didFinishLoading) {
|
||||
String fontFilename = KMManager.getKeyboardTextFontFilename();
|
||||
String fontFilename = getKeyboardTextFontFilenameOnly();
|
||||
if (!loadedFont.equals(fontFilename)) {
|
||||
webView.reload();
|
||||
}
|
||||
|
|
@ -432,8 +433,19 @@ public class WebBrowserActivity extends BaseActivity {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename without path of the display font of the current keyboard.
|
||||
*/
|
||||
private String getKeyboardTextFontFilenameOnly() {
|
||||
String fontPath = KMManager.getKeyboardTextFontFilename();
|
||||
if (fontPath == null || fontPath.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return new File(fontPath).getName();
|
||||
}
|
||||
|
||||
private void loadFont() {
|
||||
String font = KMManager.getKeyboardTextFontFilename();
|
||||
String font = getKeyboardTextFontFilenameOnly();
|
||||
if (!font.isEmpty()) {
|
||||
loadedFont = font;
|
||||
String fontUrl = String.format("%s%s", fontBaseUri, font);
|
||||
|
|
|
|||
|
|
@ -84,10 +84,8 @@ final class KMKeyboard extends WebView {
|
|||
*/
|
||||
protected static KMManager.BannerType currentBanner = KMManager.BannerType.HTML;
|
||||
|
||||
private static String txtFont = "";
|
||||
private static String oskFont = null;
|
||||
private static String dataRoot = "";
|
||||
private static String packageRoot = "";
|
||||
private static String txtFontPath = "";
|
||||
private static String oskFontPath = "";
|
||||
private final String fontUndefined = "undefined";
|
||||
private GestureDetector gestureDetector;
|
||||
private static ArrayList<OnKeyboardEventListener> kbEventListeners = null;
|
||||
|
|
@ -551,7 +549,7 @@ final class KMKeyboard extends WebView {
|
|||
* @return String
|
||||
*/
|
||||
public static String textFontFilename() {
|
||||
return txtFont;
|
||||
return txtFontPath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -559,10 +557,10 @@ final class KMKeyboard extends WebView {
|
|||
* @return String
|
||||
*/
|
||||
public static String oskFontFilename() {
|
||||
return oskFont;
|
||||
return oskFontPath;
|
||||
}
|
||||
|
||||
// REVIEW: this method seems to be unused
|
||||
// REVIEW: this method seems to be unused and undocumented. Can we remove it?
|
||||
/**
|
||||
* Return the full path to the special OSK font,
|
||||
* which is with all the keyboard assets at the root app_data folder
|
||||
|
|
@ -648,8 +646,6 @@ final class KMKeyboard extends WebView {
|
|||
}
|
||||
String kbKey = KMString.format("%s_%s", languageID, keyboardID);
|
||||
|
||||
setPackageRoot(packageID);
|
||||
|
||||
// Escape single-quoted names for javascript call
|
||||
keyboardName = keyboardName.replaceAll("\'", "\\\\'"); // Double-escaped-backslash b/c regex.
|
||||
|
||||
|
|
@ -704,16 +700,14 @@ final class KMKeyboard extends WebView {
|
|||
KMManager.getLatestKeyboardFileVersion(getContext(), packageID, keyboardID) : null;
|
||||
}
|
||||
|
||||
setPackageRoot(packageID);
|
||||
|
||||
if(kOskFont == null || kOskFont.isEmpty())
|
||||
kOskFont = kFont;
|
||||
|
||||
JSONObject jDisplayFont = makeFontObject(kFont);
|
||||
JSONObject jOskFont = makeFontObject(kOskFont);
|
||||
JSONObject jDisplayFont = makeFontObject(kFont, packageID);
|
||||
JSONObject jOskFont = makeFontObject(kOskFont, packageID);
|
||||
|
||||
txtFont = getFontFilename(jDisplayFont);
|
||||
oskFont = getFontFilename(jOskFont);
|
||||
txtFontPath = getFontFilename(kFont, packageID);
|
||||
oskFontPath = getFontFilename(kOskFont, packageID);
|
||||
|
||||
String kbKey = KMString.format("%s_%s", languageID, keyboardID);
|
||||
|
||||
|
|
@ -810,26 +804,40 @@ final class KMKeyboard extends WebView {
|
|||
}
|
||||
}
|
||||
|
||||
// Set the base path of the keyboard depending on the package ID
|
||||
private void setPackageRoot(String packageID) {
|
||||
this.dataRoot = WebViewUtils.buildAssetUrl("");
|
||||
/**
|
||||
* Return the root URL for the data folder. Even though this is a local
|
||||
* location this returns a URL with a magic domain so that it can be
|
||||
* loaded with fetch() in the webview.
|
||||
*/
|
||||
private String getDataRootUrl() {
|
||||
return WebViewUtils.buildAssetUrl("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the root path for the data folder as a file path. This should be
|
||||
* used where the file is not loaded through the webview, but is instead
|
||||
* used by the app directly.
|
||||
*/
|
||||
private String getDataRootPath() {
|
||||
return context.getDir("data", Context.MODE_PRIVATE).toString() + File.separator;
|
||||
}
|
||||
|
||||
private String getPackageRootUrl(String packageID) {
|
||||
if (packageID.equals(KMManager.KMDefault_UndefinedPackageID)) {
|
||||
this.packageRoot = this.dataRoot + KMManager.KMDefault_UndefinedPackageID + "/";
|
||||
} else {
|
||||
this.packageRoot = this.dataRoot + KMManager.KMDefault_AssetPackages + "/" + packageID + "/";
|
||||
return getDataRootUrl() + KMManager.KMDefault_UndefinedPackageID + "/";
|
||||
}
|
||||
return getDataRootUrl() + KMManager.KMDefault_AssetPackages + "/" + packageID + "/";
|
||||
}
|
||||
|
||||
private String getDataRoot() {
|
||||
return this.dataRoot;
|
||||
}
|
||||
|
||||
private String getPackageRoot() {
|
||||
return this.packageRoot;
|
||||
private String getPackageRootPath(String packageID) {
|
||||
if (packageID.equals(KMManager.KMDefault_UndefinedPackageID)) {
|
||||
return getDataRootPath() + KMManager.KMDefault_UndefinedPackageID + File.separator;
|
||||
}
|
||||
return getDataRootPath() + KMManager.KMDefault_AssetPackages + File.separator + packageID + File.separator;
|
||||
}
|
||||
|
||||
private String makeKeyboardUrl(String packageID, String keyboardID, String keyboardVersion) {
|
||||
String keyboardUrl = getPackageRoot();
|
||||
String keyboardUrl = getPackageRootUrl(packageID);
|
||||
if (packageID.equals(KMManager.KMDefault_UndefinedPackageID)) {
|
||||
keyboardUrl += keyboardID + "-" + keyboardVersion + ".js";
|
||||
} else {
|
||||
|
|
@ -917,42 +925,23 @@ final class KMKeyboard extends WebView {
|
|||
}
|
||||
|
||||
/**
|
||||
* getFontFilename
|
||||
* Parse a Font JSON object and return the font filename (ending in .ttf or .otf)
|
||||
* @param fontObj JSONObject - Font JSON object
|
||||
* @return String - Filename for the font. If font is invalid, return ""
|
||||
* Return the full path to the font file. If the font is invalid, return empty string.
|
||||
* @param font String - Font filename
|
||||
* @param packageID String - Package ID
|
||||
* @return String - Full path to the font file. If font is invalid, return "".
|
||||
*/
|
||||
private String getFontFilename(JSONObject fontObj) {
|
||||
String font = "";
|
||||
if (fontObj == null) {
|
||||
return font;
|
||||
}
|
||||
try {
|
||||
JSONArray sourceArray = fontObj.optJSONArray(KMManager.KMKey_FontFiles);
|
||||
if (sourceArray != null) {
|
||||
String fontFile;
|
||||
int length = sourceArray.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
fontFile = sourceArray.getString(i);
|
||||
if (FileUtils.hasFontExtension(fontFile)) {
|
||||
font = fontFile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String fontFile = fontObj.optString(KMManager.KMKey_FontFiles);
|
||||
if (fontFile != null) {
|
||||
if (FileUtils.hasFontExtension(fontFile)) {
|
||||
font = fontFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
KMLog.LogException(TAG, "", e);
|
||||
font = "";
|
||||
private String getFontFilename(String font, String packageID) {
|
||||
if(font == null || font.equals("")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return font;
|
||||
if (!FileUtils.hasFontExtension(font)) {
|
||||
// QUESTION: do we log this?
|
||||
return "";
|
||||
}
|
||||
|
||||
String fontRoot = KMManager.isDefaultFont(font) ? getDataRootPath() : getPackageRootPath(packageID);
|
||||
return fontRoot + font;
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
|
|
@ -1061,12 +1050,14 @@ final class KMKeyboard extends WebView {
|
|||
* the first file with a font extension which is then prefixed with the
|
||||
* path to the fonts.
|
||||
*
|
||||
* @param font A string containing either the font filename or a font JSON
|
||||
* object as a string
|
||||
* @param font A string containing either the font filename or a font
|
||||
* JSON object as a string
|
||||
* @param packageID The package ID of the keyboard
|
||||
*
|
||||
* @return JSONObject of modified font information with full paths. If font
|
||||
* is invalid, return `null`.
|
||||
*/
|
||||
private JSONObject makeFontObject(String font) {
|
||||
private JSONObject makeFontObject(String font, String packageID) {
|
||||
|
||||
if(font == null || font.equals("")) {
|
||||
return null;
|
||||
|
|
@ -1077,12 +1068,16 @@ final class KMKeyboard extends WebView {
|
|||
JSONObject jfont = new JSONObject();
|
||||
jfont.put(KMManager.KMKey_FontFamily, font.substring(0, font.length()-4));
|
||||
JSONArray jfiles = new JSONArray();
|
||||
String fontRoot = KMManager.isDefaultFont(font) ? getDataRoot() : getPackageRoot();
|
||||
String fontRoot = KMManager.isDefaultFont(font) ? getDataRootUrl() : getPackageRootUrl(packageID);
|
||||
jfiles.put(fontRoot + font);
|
||||
jfont.put(KMManager.KMKey_FontFiles, jfiles);
|
||||
return jfont;
|
||||
}
|
||||
|
||||
// REVIEW: Why do we need the complicated code below? Can this still
|
||||
// happen, or can we remove it? (see also getFontFilename)
|
||||
KMLog.LogInfo(TAG, "Got font without font extension: " + font);
|
||||
|
||||
JSONObject fontObj = new JSONObject(font);
|
||||
|
||||
// Replace "sources" key with "files"
|
||||
|
|
@ -1094,7 +1089,7 @@ final class KMKeyboard extends WebView {
|
|||
Object obj = fontObj.get(KMManager.KMKey_FontFiles);
|
||||
if (obj instanceof String) {
|
||||
String fontFile = fontObj.getString(KMManager.KMKey_FontFiles);
|
||||
String fontRoot = KMManager.isDefaultFont(fontFile) ? getDataRoot() : getPackageRoot();
|
||||
String fontRoot = KMManager.isDefaultFont(fontFile) ? getDataRootUrl() : getPackageRootUrl(packageID);
|
||||
fontObj.put(KMManager.KMKey_FontFiles, fontRoot + obj);
|
||||
return fontObj;
|
||||
} else if (obj instanceof JSONArray) {
|
||||
|
|
@ -1103,7 +1098,7 @@ final class KMKeyboard extends WebView {
|
|||
for (int i = 0; i < sourceArray.length(); i++) {
|
||||
String fontFile = sourceArray.getString(i);
|
||||
if (FileUtils.hasFontExtension(fontFile)) {
|
||||
String fontRoot = KMManager.isDefaultFont(fontFile) ? getDataRoot() : getPackageRoot();
|
||||
String fontRoot = KMManager.isDefaultFont(fontFile) ? getDataRootUrl() : getPackageRootUrl(packageID);
|
||||
fontObj.put(KMManager.KMKey_FontFiles, fontRoot + fontFile);
|
||||
fontObj.remove(KMManager.KMKey_FontSource);
|
||||
return fontObj;
|
||||
|
|
|
|||
|
|
@ -1629,6 +1629,16 @@ public final class KMManager {
|
|||
*/
|
||||
public static Typeface getFontTypeface(Context context, String fontFilename) {
|
||||
try {
|
||||
if (fontFilename == null || fontFilename.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (fontFilename.startsWith("http://") || fontFilename.startsWith("https://")
|
||||
|| fontFilename.startsWith("file://")) {
|
||||
// Font file is not local, so cannot load Typeface
|
||||
KMLog.LogError(TAG, "Font file is not local: " + fontFilename);
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((fontFilename != null) && FileUtils.hasFontExtension(fontFilename)) {
|
||||
// Ignore .woff files if Android 7.0 / 7.1 (Issue #4896)
|
||||
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) &&
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ KMManager.getFontTypeface(Context context, String fontFilename)
|
|||
: The context.
|
||||
|
||||
`fontFilename`
|
||||
: The filename of the font.
|
||||
: The filename and full path of the font.
|
||||
|
||||
### Returns
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ if it exists, `null` otherwise.
|
|||
## Description
|
||||
|
||||
Use this method to create a new typeface from the font file with
|
||||
specified filename if it exists in `assets/fonts/` folder.
|
||||
specified filename if it exists.
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -37,9 +37,10 @@ specified filename if it exists in `assets/fonts/` folder.
|
|||
|
||||
The following script illustrate the use of `getFontTypeface()`:
|
||||
|
||||
``` javascript
|
||||
``` java
|
||||
KMTextView textView = (KMTextView) findViewById(R.id.kmTextView);
|
||||
Typeface fontTypeface = KMManager.getFontTypeface(this, "aava1.ttf");
|
||||
String textFontFilename = KMManager.getKeyboardTextFontFilename();
|
||||
Typeface fontTypeface = KMManager.getFontTypeface(this, textFontFilename);
|
||||
textView.setTypeface(fontTypeface);
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,25 @@ title: KMManager.getKeyboardOskFontFilename()
|
|||
## Summary
|
||||
|
||||
The **`getKeyboardOskFontFilename()`** method returns the selected
|
||||
keyboard's OSK font filename.
|
||||
keyboard's OSK font filename and full path.
|
||||
|
||||
## Syntax
|
||||
|
||||
``` javascript
|
||||
``` java
|
||||
KMManager.getKeyboardOskFontFilename()
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
Returns the selected keyboard's OSK font filename as `String` if it has
|
||||
any, empty string otherwise.
|
||||
Returns the selected keyboard's OSK font filename and full path as
|
||||
`String` if it has any, empty string otherwise. Note that the
|
||||
on-screen keyboard will fallback to the keyboard text font if
|
||||
no OSK font is specified.
|
||||
|
||||
The OSK font should not be used for a text view, because some
|
||||
OSK fonts are appropriate for use only in the on screen keyboard;
|
||||
see [`&displayMap`](/developer/language/reference/displaymap) for
|
||||
reference.
|
||||
|
||||
## Description
|
||||
|
||||
|
|
@ -29,8 +36,8 @@ Use this method to get the OSK font filename of the selected keyboard.
|
|||
The following script illustrate the use of
|
||||
`getKeyboardOskFontFilename()`:
|
||||
|
||||
``` javascript
|
||||
String oskFontFilename = KMManager.getKeyboardOskFontFilename();
|
||||
``` java
|
||||
String oskFontFilename = KMManager.getKeyboardOskFontFilename();
|
||||
```
|
||||
|
||||
## See also
|
||||
|
|
|
|||
|
|
@ -5,18 +5,18 @@ title: KMManager.getKeyboardTextFontFilename()
|
|||
## Summary
|
||||
|
||||
The **`getKeyboardTextFontFilename()`** method returns the selected
|
||||
keyboard's text font filename.
|
||||
keyboard's text font filename and full path.
|
||||
|
||||
## Syntax
|
||||
|
||||
``` javascript
|
||||
``` java
|
||||
KMManager.getKeyboardTextFontFilename()
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
Returns the selected keyboard's text font filename as `String` if it has
|
||||
any, empty string otherwise.
|
||||
Returns the selected keyboard's text font filename and full path as
|
||||
`String` if it has any, empty string otherwise.
|
||||
|
||||
## Description
|
||||
|
||||
|
|
@ -29,8 +29,8 @@ Use this method to get the text font filename of the selected keyboard.
|
|||
The following script illustrate the use of
|
||||
`getKeyboardTextFontFilename()`:
|
||||
|
||||
``` javascript
|
||||
String textFontFilename = KMManager.getKeyboardTextFontFilename();
|
||||
``` java
|
||||
String textFontFilename = KMManager.getKeyboardTextFontFilename();
|
||||
```
|
||||
|
||||
## See also
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue