feat: added font choosing for android
This commit is contained in:
101
lib/src/utils/font_list_parser.dart
Normal file
101
lib/src/utils/font_list_parser.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:rich_editor/src/models/alias.dart';
|
||||
import 'package:rich_editor/src/models/config.dart';
|
||||
import 'package:rich_editor/src/models/family.dart';
|
||||
import 'package:rich_editor/src/models/font.dart';
|
||||
import 'package:rich_editor/src/models/system_font.dart';
|
||||
import 'package:xml2json/xml2json.dart';
|
||||
|
||||
// A simple port of FontListParser from Java to Kotlin
|
||||
// See https://stackoverflow.com/a/29533686/10835183
|
||||
class FontListParser {
|
||||
File androidFontsFile = File("/system/etc/fonts.xml");
|
||||
File androidSystemFontsFile = File("/system/etc/system_fonts.xml");
|
||||
|
||||
List<SystemFont> getSystemFonts() {
|
||||
String fontsXml;
|
||||
if (androidFontsFile.existsSync()) {
|
||||
fontsXml = androidFontsFile.path;
|
||||
} else if (androidSystemFontsFile.existsSync()) {
|
||||
fontsXml = androidSystemFontsFile.path;
|
||||
} else {
|
||||
throw ("fonts.xml does not exist on this system");
|
||||
}
|
||||
Xml2Json xml2json = new Xml2Json();
|
||||
xml2json.parse(File(fontsXml).readAsStringSync());
|
||||
Map json = jsonDecode(xml2json.toGData());
|
||||
Config parser = Config.fromJson(json['familyset']);
|
||||
List<SystemFont> fonts = <SystemFont>[];
|
||||
|
||||
for (Family family in parser.families!) {
|
||||
if (family.name != null) {
|
||||
Font font = Font();
|
||||
for (Font f in family.fonts!) {
|
||||
font = f;
|
||||
if (int.tryParse(f.weight!) == 400) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SystemFont systemFont = new SystemFont(family.name!, font.t ?? '');
|
||||
if (fonts.contains(systemFont)) {
|
||||
continue;
|
||||
}
|
||||
fonts.add(new SystemFont(family.name!, font.t ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
for (Alias alias in parser.aliases!) {
|
||||
if (alias.name == null ||
|
||||
alias.to == null ||
|
||||
int.tryParse(alias.weight ?? '') == 0) {
|
||||
continue;
|
||||
}
|
||||
for (Family family in parser.families!) {
|
||||
if (family.name == null || family.name! == alias.to) {
|
||||
continue;
|
||||
}
|
||||
for (Font font in family.fonts!) {
|
||||
if (font.weight == alias.weight) {
|
||||
fonts.add(new SystemFont(alias.name!, font.t ?? ''));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fonts.isEmpty) {
|
||||
throw Exception("No system fonts found.");
|
||||
}
|
||||
// fonts
|
||||
// print(fonts);
|
||||
return fonts;
|
||||
}
|
||||
|
||||
List<SystemFont> safelyGetSystemFonts() {
|
||||
try {
|
||||
return getSystemFonts();
|
||||
} catch (e) {
|
||||
List<List> defaultSystemFonts = [
|
||||
["cursive", "DancingScript-Regular.ttf"],
|
||||
["monospace", "DroidSansMono.ttf"],
|
||||
["sans-serif", "Roboto-Regular.ttf"],
|
||||
["sans-serif-light" "Roboto-Light.ttf"],
|
||||
["sans-serif-medium", "Roboto-Medium.ttf"],
|
||||
["sans-serif-black", "Roboto-Black.ttf"],
|
||||
["sans-serif-condensed", "RobotoCondensed-Regular.ttf"],
|
||||
["sans-serif-thin", "Roboto-Thin.ttf"],
|
||||
["serif", "NotoSerif-Regular.ttf"]
|
||||
];
|
||||
List<SystemFont> fonts = <SystemFont>[];
|
||||
for (List names in defaultSystemFonts) {
|
||||
File file = new File("/system/fonts/"+ names[1]);
|
||||
if (file.existsSync()) {
|
||||
fonts.add(new SystemFont(names[0], file.path));
|
||||
}
|
||||
}
|
||||
return fonts;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rich_editor/src/extensions/extensions.dart';
|
||||
import 'package:rich_editor/src/models/editor_state.dart';
|
||||
import 'package:rich_editor/src/models/enum.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
@@ -15,6 +18,7 @@ class JavascriptExecutorBase {
|
||||
String defaultEncoding = "UTF-8";
|
||||
|
||||
String? htmlField = "";
|
||||
var didHtmlChange = false;
|
||||
Map<CommandName, CommandState> commandStates = {};
|
||||
|
||||
init(WebViewController controller) {
|
||||
@@ -196,4 +200,88 @@ class JavascriptExecutorBase {
|
||||
static encodeHtml(String html) {
|
||||
return Uri.encodeFull(html);
|
||||
}
|
||||
|
||||
// bool shouldOverrideUrlLoading(String url) {
|
||||
// String decodedUrl;
|
||||
// try {
|
||||
// decodedUrl = decodeHtml(url);
|
||||
// } catch (e) {
|
||||
// // No handling
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (url.indexOf(editorStateChangedCallbackScheme) == 0) {
|
||||
// editorStateChanged(
|
||||
// decodedUrl.substring(editorStateChangedCallbackScheme.length));
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// editorStateChanged(String statesString) {
|
||||
// try {
|
||||
// var editorState = EditorState.fromJson(jsonDecode(statesString));
|
||||
//
|
||||
// bool currentHtmlChanged = this.htmlField != editorState.html;
|
||||
// this.htmlField = editorState.html;
|
||||
//
|
||||
// retrievedEditorState(editorState.didHtmlChange, editorState.commandStates)
|
||||
//
|
||||
// if (currentHtmlChanged) {
|
||||
// fireHtmlChangedListenersAsync(editorState.html);
|
||||
// }
|
||||
// }
|
||||
// catch (e) {
|
||||
// throw("Could not parse command states: $statesString $e");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// retrievedEditorState(bool didHtmlChange,
|
||||
// Map<CommandName, CommandState> commandStates) {
|
||||
// if (this.didHtmlChange != didHtmlChange) {
|
||||
// this.didHtmlChange = didHtmlChange;
|
||||
// didHtmlChangeListeners.forEach {
|
||||
// it.didHtmlChange(didHtmlChange);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// handleRetrievedCommandStates(commandStates)
|
||||
// }
|
||||
//
|
||||
// handleRetrievedCommandStates(Map<CommandName, CommandState> commandStates) {
|
||||
// determineDerivedCommandStates(commandStates)
|
||||
//
|
||||
// this.commandStates = commandStates;
|
||||
//
|
||||
// commandStatesChangedListeners.forEach {
|
||||
// it.invoke(this.commandStates)
|
||||
// }
|
||||
// }
|
||||
|
||||
// determineDerivedCommandStates(Map<CommandName, CommandState> commandStates) {
|
||||
// commandStates[CommandName.FORMATBLOCK]?.let { formatCommandState ->
|
||||
// commandStates.put(CommandName.H1, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h1")))
|
||||
// commandStates.put(CommandName.H2, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h2")))
|
||||
// commandStates.put(CommandName.H3, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h3")))
|
||||
// commandStates.put(CommandName.H4, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h4")))
|
||||
// commandStates.put(CommandName.H5, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h5")))
|
||||
// commandStates.put(CommandName.H6, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "h6")))
|
||||
// commandStates.put(CommandName.P, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "p")))
|
||||
// commandStates.put(CommandName.PRE, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "pre")))
|
||||
// commandStates.put(CommandName.BR, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "")))
|
||||
// commandStates.put(CommandName.BLOCKQUOTE, CommandState(formatCommandState.executable, isFormatActivated(formatCommandState, "blockquote")))
|
||||
// }
|
||||
//
|
||||
// commandStates[CommandName.INSERTHTML]?.let { insertHtmlState ->
|
||||
// commandStates.put(CommandName.INSERTLINK, insertHtmlState)
|
||||
// commandStates.put(CommandName.INSERTIMAGE, insertHtmlState)
|
||||
// commandStates.put(CommandName.INSERTCHECKBOX, insertHtmlState)
|
||||
// }
|
||||
// }
|
||||
|
||||
// String isFormatActivated(CommandState formatCommandState, String format) {
|
||||
// return (formatCommandState.value == format)
|
||||
// .toString(); // rich_text_editor.js reports boolean values as string, so we also have to convert it to string
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user