allow using user-provided font

fixes #494
This commit is contained in:
Helium314 2025-01-17 21:47:13 +01:00
parent c581e9601b
commit 9a2009d182
9 changed files with 94 additions and 3 deletions

View file

@ -95,6 +95,7 @@ public class KeyboardView extends View {
@NonNull
private final Paint mPaint = new Paint();
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
protected final Typeface mTypeface;
public KeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.keyboardViewStyle);
@ -144,6 +145,7 @@ public class KeyboardView extends View {
keyAttr.recycle();
mPaint.setAntiAlias(true);
mTypeface = Settings.getInstance().readCustomTypeface();
}
@Nullable
@ -381,7 +383,7 @@ public class KeyboardView extends View {
float labelBaseline = centerY;
final String label = key.getLabel();
if (label != null) {
paint.setTypeface(key.selectTypeface(params));
paint.setTypeface(mTypeface == null ? key.selectTypeface(params) : mTypeface);
paint.setTextSize(key.selectTextSize(params));
final float labelCharHeight = TypefaceUtils.getReferenceCharHeight(paint);
final float labelCharWidth = TypefaceUtils.getReferenceCharWidth(paint);

View file

@ -798,7 +798,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
final int width = key.getWidth();
final int height = key.getHeight();
paint.setTextAlign(Align.CENTER);
paint.setTypeface(Typeface.DEFAULT);
paint.setTypeface(mTypeface == null ? Typeface.DEFAULT : mTypeface);
paint.setTextSize(mLanguageOnSpacebarTextSize);
final String customText = Settings.getInstance().getCurrent().mSpaceBarText;
final String spaceText;

View file

@ -156,6 +156,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
val params = KeyDrawParams()
params.updateParams(clipboardLayoutParams.bottomRowKeyboardHeight, keyVisualAttr)
Settings.getInstance().readCustomTypeface()?.let { params.mTypeface = it }
setupClipKey(params)
setupBottomRowKeyboard(editorInfo, keyboardActionListener)

View file

@ -8,6 +8,7 @@ package helium314.keyboard.keyboard.internal;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextUtils;
@ -20,6 +21,7 @@ import androidx.appcompat.widget.AppCompatTextView;
import helium314.keyboard.keyboard.Key;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.StringUtilsKt;
import helium314.keyboard.latin.settings.Settings;
import java.util.HashSet;
@ -33,6 +35,7 @@ public class KeyPreviewView extends AppCompatTextView {
private final Rect mBackgroundPadding = new Rect();
private static final HashSet<String> sNoScaleXTextSet = new HashSet<>();
private final Typeface mTypeface;
public KeyPreviewView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
@ -41,6 +44,7 @@ public class KeyPreviewView extends AppCompatTextView {
public KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
setGravity(Gravity.CENTER);
mTypeface = Settings.getInstance().readCustomTypeface();
}
public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams) {
@ -54,7 +58,8 @@ public class KeyPreviewView extends AppCompatTextView {
setCompoundDrawables(null, null, null, null);
setTextColor(drawParams.mPreviewTextColor);
setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams));
setTypeface(key.selectPreviewTypeface(drawParams));
// wie hier machen?
setTypeface(mTypeface == null ? key.selectPreviewTypeface(drawParams) : mTypeface);
// TODO Should take care of temporaryShiftLabel here.
setTextAndScaleX(key.getPreviewLabel());
}

View file

@ -7,6 +7,7 @@ import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
import android.graphics.BitmapFactory
import android.graphics.Typeface
import android.net.Uri
import android.os.Build
import android.os.Bundle
@ -36,12 +37,14 @@ import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.FileUtils
import helium314.keyboard.latin.customIconNames
import helium314.keyboard.latin.databinding.ReorderDialogItemBinding
import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.ResourceUtils
import helium314.keyboard.latin.utils.confirmDialog
import helium314.keyboard.latin.utils.getStringResourceOrName
import helium314.keyboard.latin.utils.infoDialog
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.io.File
import java.lang.Float.max
import java.lang.Float.min
import java.util.*
@ -86,6 +89,12 @@ class AppearanceSettingsFragment : SubScreenFragment() {
loadImage(uri, true, true)
}
private val fontFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
val uri = it.data?.data ?: return@registerForActivityResult
saveCustomTypeface(uri)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.prefs_screen_appearance)
@ -106,6 +115,7 @@ class AppearanceSettingsFragment : SubScreenFragment() {
}
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage(false) }
findPreference<Preference>("custom_background_image_landscape")?.setOnPreferenceClickListener { onClickLoadImage(true) }
findPreference<Preference>("custom_font")?.setOnPreferenceClickListener { onClickCustomFont() }
findPreference<Preference>(Settings.PREF_CUSTOM_ICON_NAMES)?.setOnPreferenceClickListener {
if (needsReload)
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
@ -389,6 +399,44 @@ class AppearanceSettingsFragment : SubScreenFragment() {
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
}
private fun onClickCustomFont(): Boolean {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType("*/*")
val fontFile = Settings.getCustomFontFile(requireContext())
if (fontFile.exists()) {
AlertDialog.Builder(requireContext())
.setTitle(R.string.custom_font)
.setPositiveButton(R.string.load) { _, _ -> fontFilePicker.launch(intent) }
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton(R.string.delete) { _, _ ->
fontFile.delete()
Settings.clearCachedTypeface()
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
}
.show()
} else {
fontFilePicker.launch(intent)
}
return true
}
private fun saveCustomTypeface(uri: Uri) {
val fontFile = Settings.getCustomFontFile(requireContext())
val tempFile = File(DeviceProtectedUtils.getFilesDir(context), "temp_file")
FileUtils.copyContentUriToNewFile(uri, requireContext(), tempFile)
try {
val typeface = Typeface.createFromFile(tempFile)
fontFile.delete()
tempFile.renameTo(fontFile)
Settings.clearCachedTypeface()
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
} catch (_: Exception) {
infoDialog(requireContext(), R.string.file_read_error)
tempFile.delete()
}
}
private fun setupScalePrefs(prefKey: String, defaultValue: Float) {
val prefs = sharedPreferences
val pref = findPreference(prefKey) as? SeekBarDialogPreference

View file

@ -14,6 +14,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -196,6 +197,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
// static cache for background images to avoid potentially slow reload on every settings reload
private final static Drawable[] sCachedBackgroundImages = new Drawable[4];
private static Typeface sCachedTypeface;
private Map<String, Integer> mCustomToolbarKeyCodes = null;
private Map<String, Integer> mCustomToolbarLongpressCodes = null;
@ -729,4 +731,25 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
mCustomToolbarLongpressCodes = ToolbarUtilsKt.readCustomLongpressCodes(mPrefs);
return mCustomToolbarLongpressCodes.get(key.name());
}
public static File getCustomFontFile(final Context context) {
return new File(DeviceProtectedUtils.getFilesDir(context), "custom_font");
}
@Nullable
public Typeface readCustomTypeface() {
// dammit, dann würde wenns keins gibt bei jedem zugriff gesucht -> 2 variablen nehmen? custom und hasCustom?
// ein clear brauchen wir sowieso on theme changed (und auch triggern wenn man ne font setzt/löscht)
// try/catch!
if (sCachedTypeface == null) {
try {
sCachedTypeface = Typeface.createFromFile(getCustomFontFile(mContext));
} catch (Exception e) { }
}
return sCachedTypeface;
}
public static void clearCachedTypeface() {
sCachedTypeface = null;
}
}

View file

@ -15,6 +15,7 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ShapeDrawable;
@ -155,11 +156,14 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mToolbar = findViewById(R.id.toolbar);
mToolbarContainer = findViewById(R.id.toolbar_container);
final Typeface customTypeface = Settings.getInstance().readCustomTypeface();
for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) {
final TextView word = new TextView(context, null, R.attr.suggestionWordStyle);
word.setContentDescription(getResources().getString(R.string.spoken_empty_suggestion));
word.setOnClickListener(this);
word.setOnLongClickListener(this);
if (customTypeface != null)
word.setTypeface(customTypeface);
colors.setBackground(word, ColorType.STRIP_BACKGROUND);
mWordViews.add(word);
final View divider = inflater.inflate(R.layout.suggestion_divider, null);

View file

@ -313,6 +313,8 @@
<string name="prefs_bottom_padding_scale">Bottom padding scale</string>
<!-- Title of the setting for customizing space bar text -->
<string name="prefs_space_bar_text">Custom text on space bar</string>
<!-- Title of the setting for adding / removing custom font file -->
<string name="custom_font">Set custom font from file</string>
<!-- Description for English (UK) keyboard subtype [CHAR LIMIT=25]
(UK) should be an abbreviation of United Kingdom to fit in the CHAR LIMIT. -->
<string name="subtype_en_GB">English (UK)</string>

View file

@ -117,6 +117,12 @@
android:defaultValue=""
android:persistent="true" />
<Preference
android:key="custom_font"
android:title="@string/custom_font"
android:defaultValue=""
android:persistent="true" />
</PreferenceCategory>
</PreferenceScreen>