Compare commits

...

15 Commits

Author SHA1 Message Date
Jules Aguillon
3b1c652370 Release 1.15.0 (22) 2022-05-01 23:06:18 +02:00
Tibor Billes
8cb1789eeb Add support for Hungarian layout (#127) 2022-05-01 22:51:11 +02:00
Jules Aguillon
04a7ec4bb8 Fix latched pointers accumulating on the same key
It was possible to latch and lock the same modifier several time at the
same time independently. Remove that.
2022-05-01 00:11:52 +02:00
Jules Aguillon
8e0d38c257 Fix crash when IME not enabled
This is unexpected but happened to a user. Perhaps because the OS
returned bogus or fake results in imm.getEnabledInputMethodList ?
2022-05-01 00:00:15 +02:00
Jules Aguillon
b72635b887 Fix modifiers not cleared when presses overlap
When typing fast, a second key might be pressed before the first is
released.

Clearing modifiers earlier would prevent this but would break modifiers
placed in corners (especially the accent keys). Instead, don't take
latched modifiers into account when registering the second press.

A new flag is needed to not interfere with holding modifers, which is
merged with the norepeat flag.
2022-04-30 23:47:09 +02:00
Jules Aguillon
84af72c222 Record activated modifiers on key down
The View no longer keeps flags for something other than rendering.
2022-04-30 23:17:20 +02:00
marciozomb13
2df4764557 Strings PT: App partially renamed to improve globalization (#134) 2022-04-30 11:01:03 +02:00
Jules Aguillon
39952f8bdf Remove build dependency on Fontforge
The required version of fontforge (from 2020!) is not available in many
distros. This is an annoying for contributors and greatly complicated
the CI and F-Droid scripts.

The generated font file is now included in the sources. Fontforge is
still needed when adding new glyphs but this is not a common operation.
2022-04-24 20:52:36 +02:00
Djuric
ab4c73f9f3 Add build instructions to the contributing page (#130) 2022-04-24 19:59:36 +02:00
matthiakl
e52e537fd7 Added neo 2 layout (#125)
* Added neo 2 layout

* Move accents away from screen edge into second row
2022-04-24 19:58:33 +02:00
Jules Aguillon
2900e8d197 Add Double acute diacritic
Will be used by the Hungarian language.
2022-04-24 01:15:41 +02:00
Jules Aguillon
d8e475467a Fix cedilla glyph is inverted 2022-04-24 00:49:48 +02:00
Jules Aguillon
fec3f109c9 Add support for Lithuanian
Requires two new diacritics: ogonek and dot_above.

The new accents are also added to the Latvian layout as the two language
can be close but not to the other localized layouts. A new mechanism is
needed to reproducibly add extra keys to layouts without manual
placement.
2022-04-24 00:41:49 +02:00
Jules Aguillon
f9f44fbd7d Update contributing guidelines
- Improve layout guidelines
- Adding a locale
- Mention character close to the edges of the screen
- Allow partially translating the app title
2022-04-24 00:41:49 +02:00
Benjamin
914599f16a German translation update 2022-04-23 20:12:52 +02:00
26 changed files with 299 additions and 89 deletions

View File

@@ -9,19 +9,6 @@ jobs:
Build-Apk:
runs-on: ubuntu-latest
steps:
- name: Cache fontforge and extra dependencies
uses: actions/cache@v2
with:
path: /usr/local/bin
key: usr-local-bin
- name: Install latest FontForge version (using AppImage)
run: |
# Get most recent version of FontForge
# Using AppImage there is no dependecy problem, it is the latest version and it's easier to cache
cd /usr/local/bin
sudo wget -c -N https://github.com/fontforge/fontforge/releases/download/20220308/FontForge-2022-03-08-582bd41-x86_64.AppImage
sudo chmod +x ./FontForge-2022-03-08-582bd41-x86_64.AppImage
sudo ln --symbolic --force /usr/local/bin/FontForge-2022-03-08-582bd41-x86_64.AppImage /usr/local/bin/fontforge
- uses: actions/setup-java@v2
with:
distribution: 'zulu' # See 'Supported distributions' for available options
@@ -36,11 +23,11 @@ jobs:
- name: Restore debug keystore from github Secrets
run: |
mkdir -p _build
cd "$GITHUB_WORKSPACE/_build"
cd "_build"
# Check if exist and use the secret named DEBUG_KEYSTORE
# The contents of the secret can be obtained -
# from the debug.keystore.asc from you local _build folder
if [[ ! "${{ secrets.DEBUG_KEYSTORE }}" == "" ]]; then
if [[ ! "${{ secrets.DEBUG_KEYSTORE }}" = "" ]]; then
echo "${{ secrets.DEBUG_KEYSTORE }}" > "debug.keystore.asc"
if [[ -s "debug.keystore.asc" ]]; then
gpg -d --passphrase "debug0" --batch "debug.keystore.asc" > "debug.keystore"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="21" android:versionName="1.14.2" android:hardwareAccelerated="false">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="22" android:versionName="1.15.0" android:hardwareAccelerated="false">
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="30"/>
<application android:label="@string/app_name" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="false">
<service android:name="juloo.keyboard2.Keyboard2" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD">

View File

@@ -12,7 +12,8 @@ Fortunately, there's not many dependencies:
- Android SDK: build tools (minimum `28.0.1`), platform `30`
- Make sure to have the `$ANDROID_HOME` environment variable set.
For Nix users, there's a `shell.nix` for setting-up the right environment.
For Nix users, the right environment can be obtained with `nix-shell ./shell.nix`.
Instructions to install Nix are [here](https://nixos.wiki/wiki/Nix_Installation_Guide).
Building the debug apk:
@@ -20,8 +21,7 @@ Building the debug apk:
make
```
If the build succeed, the debug apk is located in
`_build/juloo.keyboard2.debug.apk`.
If the build succeed, the debug apk is located in `_build/juloo.keyboard2.debug.apk`.
## Using the local debug.keystore on the Github CI actions
@@ -78,26 +78,55 @@ make installd
## Guidelines
### Add a localized layout
### Adding a programming layout
Localized layouts (a layout specific to a language) are generally accepted.
A programming layout must contains every ASCII characters.
The current programming layouts are: QWERTY, Dvorak.
Ideally, programming layouts should allow to type every Latin-script languages
by containing every dead-keys. See for example: 0bf7ff5 (Latvian), 573c13f (Swedish).
It is also possible to add some characters that are hidden in other languages,
for example 93e84ba (ß), though the space is limited.
Layouts are defined in XML, see `res/xml/qwerty.xml`. An entry must be added to
the layout option in `res/values/arrays.xml`, to both `pref_layout_values`
(correspond to the file name) and `pref_layout_entries` (display name).
The layout must also be referenced in `srcs/juloo.keyboard2/Config.java` in
`layoutId_of_string`.
Some users cannot easily type the characters close the the edges of the screen
due to a bulky phone case. It is best to avoid placing important characters
there (such as the digits or punctuation).
### Adding a localized layout
Localized layouts (a layout specific to a language) are gladly accepted.
See for example: 4333575 (Bulgarian), 88e2175 (Latvian), 133b6ec (German).
This keyboard is intended for programmers. If your language uses the Latin script, make sure it is possible to type every letters on the QWERTY keyboard.
This is generally done using dead-keys, for example: 0bf7ff5 (Latvian), 573c13f (Swedish).
It is also possible to add some characters that are hidden in other languages, for example 93e84ba (ß), though the space is limited.
They don't need to contain every ASCII characters (although it's useful in
passwords) and dead-keys.
### Add a programming layout
### Adding support for a language
A programming layout must contains every ASCII characters as well as every dead-keys.
Currently, the only example is QWERTY.
Supported locales are defined in `res/xml/method.xml`.
The attributes `languageTag` and `imeSubtypeLocale` define a locale, the
attribute `imeSubtypeExtraValue` defines the default layout and the dead-keys
and other extra keys to show.
### Translations
Translations are always welcome ! See for example: 1723288 (Latvian), baf867a (French).
The app can be translated by writing `res/values-<language code>/strings.xml` (for example `values-fr`, `values-lv`), based on the default: `res/values/strings.xml` (English).
Translations are always welcome !
The store description is found in `metadata/android/<locale>/`, `short_description.txt` and `full_description.txt`.
The full description changes very infrequently (it was changed once in 6 years). But if it changes too much, outdated translation might be removed.
See for example: 1723288 (Latvian), baf867a (French).
The app can be translated by writing `res/values-<language code>/strings.xml`
(for example `values-fr`, `values-lv`), based on the default:
`res/values/strings.xml` (English).
Translating changelogs is not useful because they evolve too fast. Changelogs are generally written entirely just before a release, translating them would delay releases too much. Old changelogs are not shown to anyone currently.
The store description is found in `metadata/android/<locale>/`,
`short_description.txt` and `full_description.txt`.
Translating changelogs is not useful. Changelogs are written quickly just
before a release and older ones are never shown to anyone currently.
The app name might be partially translated, the "unexpected" word should remain
untranslated.

View File

@@ -22,7 +22,10 @@ clean:
rm -rf _build/*.dex _build/class _build/gen _build/*.apk _build/*.unsigned-apk \
_build/*.idsig _build/assets
.PHONY: release debug installd clean
rebuild_special_font:
cd srcs/special_font && fontforge -lang=ff -script build.pe *.svg
.PHONY: release debug installd clean rebuild_special_font
$(shell mkdir -p _build)
@@ -85,6 +88,11 @@ _build/%.unaligned-apk: $(addprefix _build/,$(APK_EXTRA_FILES)) $(MANIFEST_FILE)
-I $(ANDROID_PLATFORM)/android.jar -F "$@" $(AAPT_PACKAGE_FLAGS)
cd $(@D) && $(ANDROID_BUILD_TOOLS)/aapt add $(@F) $(APK_EXTRA_FILES)
# Copy the special font file into _build because aapt requires relative paths
_build/assets/special_font.ttf: srcs/special_font/result.ttf
mkdir -p $(@D)
cp "$<" "$@"
# R.java
GEN_DIR = _build/gen
@@ -95,15 +103,6 @@ $(R_FILE): $(RES_FILES) $(MANIFEST_FILE)
$(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(RES_DIR) -J $(GEN_DIR) \
-M $(MANIFEST_FILE) -I $(ANDROID_PLATFORM)/android.jar
# Special font
SPECIAL_FONT_GLYPHS = $(wildcard $(CURDIR)/srcs/special_font/*.svg)
SPECIAL_FONT_SCRIPT = $(CURDIR)/srcs/special_font/build.pe
_build/assets/special_font.ttf: $(SPECIAL_FONT_SCRIPT) $(SPECIAL_FONT_GLYPHS)
mkdir -p $(@D)
fontforge -lang=ff -script $(SPECIAL_FONT_SCRIPT) $(CURDIR)/$@ $(SPECIAL_FONT_GLYPHS)
# Compile java classes and build classes.dex
OBJ_DIR = _build/class

View File

@@ -0,0 +1,7 @@
Support languages: Lithuanian, Hungarian (@tbilles)
New layouts: Neo2 (@matthiakl)
Translation improvements (@polyctena, @marciozomb13)
Fix modifiers applied twice when typing quickly. Some other fixes.
Many thanks to the contributors: @matthiakl, @polyctena, @marciozomb13, @dircsem

View File

@@ -9,6 +9,8 @@
<string name="pref_accents_e_selected">Akzente nur für die gewählte Sprache anzeigen</string>
<string name="pref_accents_e_all">Alle Akzente anzeigen</string>
<string name="pref_accents_e_none">Akzente verbergen</string>
<string name="pref_programming_layout_title">Tastaturlayout zum Programmieren</string>
<string name="pref_programming_layout_none">Keines</string>
<string name="pref_category_typing">Tippen</string>
<string name="pref_swipe_dist_title">Länge der Wischgeste</string>
<string name="pref_swipe_dist_summary">Abstand der Zeichen in den Ecken der Tasten (%s)</string>
@@ -20,6 +22,8 @@
<string name="pref_vibrate_duration_title">Dauer</string>
<string name="pref_precise_repeat_title">Präzise Cursorsteuerung</string>
<string name="pref_precise_repeat_summary">Geschwindigkeit der Tastenwiederholung durch weniger oder mehr Wischen anpassen</string>
<string name="pref_lockable_keys_title">Sperrbare Hilfstasten</string>
<string name="pref_lockable_keys_summary">Hilfstasten, die durch zweimaliges Tippen gesperrt (eingerastet) werden können</string>
<string name="pref_category_style">Design</string>
<string name="pref_margin_bottom_title">Unterer Abstand</string>
<string name="pref_keyboard_height_title">Höhe der Tastatur</string>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" product="debug">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string>
<string name="settings_activity_label">Configurações Unexpected Keyboard</string>
<string name="app_name" product="debug">Teclado Unexpected</string>
<string name="app_name" product="default">Teclado Unexpected</string>
<string name="settings_activity_label">Configurar Teclado Unexpected</string>
<string name="pref_category_layout">Layout</string>
<string name="pref_layout_title">Mudar layout do teclado</string>
<string name="pref_layout_e_system">Mesmo do sistema</string>

View File

@@ -11,8 +11,10 @@
<item>qwerty_sv_se</item>
<item>ru_jcuken</item>
<item>qwertz</item>
<item>qwertz_hu</item>
<item>bgph1</item>
<item>dvorak</item>
<item>neo2</item>
</string-array>
<string-array name="pref_layout_entries">
<item>@string/pref_layout_e_system</item>
@@ -25,8 +27,10 @@
<item>QWERTY (Swedish)</item>
<item>ЙЦУКЕН (Русский)</item>
<item>QWERTZ</item>
<item>QWERTZ (Hungarian)</item>
<item>Bulgarian (Phonetic Traditional)</item>
<item>Dvorak</item>
<item>Neo 2</item>
</string-array>
<string-array name="pref_programming_layout_values">
<item>none</item>

View File

@@ -13,9 +13,9 @@
</row>
<row>
<key key0="a" key2="1" key4="!"/>
<key key0="o" key1="accent_macron" key2="2" key3="\@"/>
<key key0="e" key1="accent_caron" key2="3" key3="\#"/>
<key key0="u" key2="4" key3="$"/>
<key key0="o" key1="accent_macron" key2="2" key3="\@" key4="accent_ogonek"/>
<key key0="e" key1="accent_caron" key2="3" key3="\#" key4="accent_dot_above"/>
<key key0="u" key2="4" key3="$" key4="accent_double_aigu"/>
<key key0="i" key2="5" key3="%"/>
<key key0="d" key2="6" key3="^"/>
<key key0="h" key2="7" key3="&amp;"/>

View File

@@ -6,8 +6,10 @@
<subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty"/>
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_es,extra_keys=accent_grave|accent_aigu|accent_tilde|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=azerty,extra_keys=accent_grave|accent_aigu|accent_circonflexe|accent_cedille|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwertz_hu,extra_keys=accent_aigu|accent_trema|accent_ogonek|€"/>
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_grave|accent_aigu|€"/>
<subtype android:label="%s" android:languageTag="ko" android:imeSubtypeLocale="ko_KR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_ko"/>
<subtype android:label="%s" android:languageTag="lt" android:imeSubtypeLocale="lt_LT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_ogonek|accent_caron|accent_dot_above|accent_macron|€"/>
<subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_lv,extra_keys=accent_caron|accent_cedille|accent_macron|€"/>
<subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_pt,extra_keys=accent_aigu|accent_cedille|accent_circonflexe|accent_grave|accent_tilde|€"/>
<subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=ru_jcuken"/>

49
res/xml/neo2.xml Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard bottom_row="false">
<row>
<key key0="x" key1="°" key2="1" key4="…"/>
<key key0="v" key1="§" key2="2" key4="_"/>
<key key0="l" key2="3" key4="["/>
<key key0="c" key2="4" key4="]"/>
<key key0="w" key2="5" key4="^"/>
<key key0="k" key2="6" key4="!"/>
<key key0="h" key2="7" key4="&lt;"/>
<key key0="g" key2="8" key4="&gt;"/>
<key key0="f" key2="9" key3="f11_placeholder" key4="="/>
<key key0="q" key2="0" key3="f12_placeholder" key4="&amp;"/>
<key key0="ß" key1="-"/>
</row>
<row>
<key key0="u" key1="tab" key2="accent_circonflexe" key4="\\"/>
<key key0="i" key2="accent_caron" key4="/"/>
<key key0="a" key2="accent_dot_above" key4="{"/>
<key key0="e" key2="accent_macron" key4="}"/>
<key key0="o" key2="accent_trema" key4="*"/>
<key key0="s" key2="accent_tilde" key4="\?"/>
<key key0="n" key2="accent_cedille" key4="("/>
<key key0="r" key2="accent_grave" key4=")"/>
<key key0="t" key2="accent_aigu" key4="-"/>
<key key0="d" key2="accent_ring" key4=":"/>
<key key0="y" key2="accent_double_aigu" key3="\@"/>
</row>
<row>
<key width="1.5" key0="shift" key1="esc"/>
<key key0="ü" key4="\#"/>
<key key0="ö" key4="$"/>
<key key0="ä" key4="|"/>
<key key0="p" key4="~"/>
<key key0="z" key4="`"/>
<key key0="b" key4="+"/>
<key key0="m" key4="%"/>
<key key0="." key1="," key3="&quot;" key4="'"/>
<key width="1.5" key0="backspace" key2="delete"/>
</row>
<row height="0.95">
<key width="1.8" key0="ctrl" key2="meta" key4="switch_numeric"/>
<key width="1.2" key0="fn" key1="alt" key2="change_method" key3="switch_emoji" key4="config"/>
<key width="4.0" key0="space" key1="switch_programming" edgekeys="true"/>
<key width="1.2" key1="up" key2="right" key3="left" key4="down" edgekeys="true"/>
<key key0="j" key4=";"/>
<key width="1.8" key0="enter" key2="action"/>
</row>
</keyboard>

View File

@@ -14,13 +14,13 @@
</row>
<row>
<key shift="0.5" key0="a" key1="tab" key2="`"/>
<key key0="s" key1="accent_ring" key3="ß"/>
<key key0="s" key1="accent_ring" key3="ß" key4="accent_ogonek"/>
<key key0="d" key1="accent_grave" key2="£" key3="accent_aigu"/>
<key key0="f"/>
<key key0="f" key1="accent_dot_above"/>
<key key0="g" key1="accent_caron" key2="-" key3="_"/>
<key key0="h" key2="=" key3="+"/>
<key key0="j" key1="accent_trema" key2="accent_circonflexe" key4="}" key3="{"/>
<key key0="k" key3="[" key4="]"/>
<key key0="k" key1="accent_double_aigu" key3="[" key4="]"/>
<key key0="l" key2="|" key3="\\"/>
</row>
<row>

View File

@@ -14,9 +14,9 @@
</row>
<row>
<key shift="0.5" key0="a" key1="ā" key2="tab"/>
<key key0="s" key1="š" key3="ß"/>
<key key0="s" key1="š" key3="ß" key4="accent_ogonek"/>
<key key0="d" key2="£"/>
<key key0="f"/>
<key key0="f" key1="accent_dot_above"/>
<key key0="g" key1="ģ"/>
<key key0="h" key2="accent_macron" key3="accent_caron" key4="accent_cedille"/>
<key key0="j" key1="+" key2="=" key3="-" key4="_"/>

37
res/xml/qwertz_hu.xml Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<keyboard>
<row>
<key key0="q" key2="0" key4="esc"/>
<key key0="w" key1="'" key2="1" key4="|"/>
<key key0="e" key1="&quot;" key2="2" key4="é"/>
<key key0="r" key2="3" key4="^"/>
<key key0="t" key1="!" key2="4" key4="f11_placeholder"/>
<key key0="z" key1="%" key2="5" key3="°" key4="f12_placeholder"/>
<key key0="u" key1="ű" key2="6" key3="ü" key4="ú"/>
<key key0="i" key1="=" key2="7" key3="`" key4="í"/>
<key key0="o" key1="ő" key2="8" key3="ö" key4="ó"/>
<key key0="p" key1="9"/>
</row>
<row>
<key shift="0.5" key0="a" key1="tab" key4="á"/>
<key key0="s" key1="§" key2="\\" key3="[" key4="]"/>
<key key0="d" key3="{" key4="}"/>
<key key0="f" key3="+"/>
<key key0="g" key3="*"/>
<key key0="h"/>
<key key0="j"/>
<key key0="k" key3="(" key4=")"/>
<key key0="l" key3="/"/>
</row>
<row>
<key width="1.5" key0="shift"/>
<key key0="y" key3="&lt;" key4="&gt;"/>
<key key0="x" key4="\#"/>
<key key0="c" key4="&amp;"/>
<key key0="v" key4="\@"/>
<key key0="b" key1="\?" key3="," key4=";"/>
<key key0="n" key1=":" key3="."/>
<key key0="m" key1="_" key3="-"/>
<key width="1.5" key0="backspace" key2="delete"/>
</row>
</keyboard>

View File

@@ -226,7 +226,9 @@ final class Config
case "qwerty": return R.xml.qwerty;
case "qwerty_sv_se": return R.xml.qwerty_sv_se;
case "qwertz": return R.xml.qwertz;
case "qwertz_hu": return R.xml.qwertz_hu;
case "ru_jcuken": return R.xml.local_ru_jcuken;
case "neo2": return R.xml.neo2;
default: return R.xml.qwerty; // The config might store an invalid layout, don't crash
}
}

View File

@@ -76,6 +76,19 @@ class KeyModifier
return (char)KeyCharacterMap.getDeadChar('\u02DA', c);
case KeyValue.FLAG_ACCENT_MACRON:
return (char)KeyCharacterMap.getDeadChar('\u00AF', c);
case KeyValue.FLAG_ACCENT_OGONEK:
return (char)KeyCharacterMap.getDeadChar('\u02DB', c);
case KeyValue.FLAG_ACCENT_DOT_ABOVE:
return (char)KeyCharacterMap.getDeadChar('\u02D9', c);
case KeyValue.FLAG_ACCENT_DOUBLE_AIGU:
switch (c)
{
// Composite characters: a̋ e̋ i̋ m̋ ӳ
case 'o': return 'ő';
case 'u': return 'ű';
case ' ': return '˝';
default: return c;
}
case KeyValue.FLAG_ACCENT_ORDINAL:
switch (c)
{

View File

@@ -20,7 +20,8 @@ class KeyValue
// Behavior flags
public static final int FLAG_LATCH = 1;
public static final int FLAG_LOCK = (1 << 1);
public static final int FLAG_NOREPEAT = (1 << 2);
// Special keys are not repeated and don't clear latched modifiers
public static final int FLAG_SPECIAL = (1 << 2);
public static final int FLAG_NOCHAR = (1 << 3);
public static final int FLAG_PRECISE_REPEAT = (1 << 4);
@@ -39,6 +40,8 @@ class KeyValue
public static final int FLAG_META = (1 << 14);
// Accent flags
public static final int FLAG_ACCENT_DOUBLE_AIGU = (1 << 9);
public static final int FLAG_ACCENT_DOT_ABOVE = (1 << 15);
public static final int FLAG_ACCENT1 = (1 << 16); // Grave
public static final int FLAG_ACCENT2 = (1 << 17); // Aigu
public static final int FLAG_ACCENT3 = (1 << 18); // Circonflexe
@@ -53,12 +56,14 @@ class KeyValue
public static final int FLAG_ACCENT_ORDINAL = (1 << 28);
public static final int FLAG_ACCENT_ARROWS = (1 << 29);
public static final int FLAG_ACCENT_BOX = (1 << 30);
public static final int FLAG_ACCENT_OGONEK = (1 << 31);
public static final int FLAGS_ACCENTS = FLAG_ACCENT1 | FLAG_ACCENT2 |
FLAG_ACCENT3 | FLAG_ACCENT4 | FLAG_ACCENT5 | FLAG_ACCENT6 |
FLAG_ACCENT_CARON | FLAG_ACCENT_MACRON | FLAG_ACCENT_SUPERSCRIPT |
FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_ORDINAL | FLAG_ACCENT_ARROWS |
FLAG_ACCENT_BOX | FLAG_ACCENT_RING;
FLAG_ACCENT_BOX | FLAG_ACCENT_RING | FLAG_ACCENT_OGONEK |
FLAG_ACCENT_DOT_ABOVE | FLAG_ACCENT_DOUBLE_AIGU;
// Language specific keys that are removed from the keyboard by default
public static final int FLAG_LOCALIZED = (1 << 25);
@@ -131,7 +136,7 @@ class KeyValue
private static void addModifierKey(String name, String symbol, int extra_flags)
{
addKey(name, symbol, CHAR_NONE, EVENT_NONE,
FLAG_LATCH | FLAG_NOCHAR | FLAG_NOREPEAT | extra_flags);
FLAG_LATCH | FLAG_NOCHAR | FLAG_SPECIAL | extra_flags);
}
private static void addSpecialKey(String name, String symbol, int event)
@@ -141,7 +146,7 @@ class KeyValue
private static void addSpecialKey(String name, String symbol, int event, int flags)
{
addKey(name, symbol, CHAR_NONE, event, flags | FLAG_NOREPEAT);
addKey(name, symbol, CHAR_NONE, event, flags | FLAG_SPECIAL);
}
private static void addEventKey(String name, String symbol, int event)
@@ -169,6 +174,9 @@ class KeyValue
addModifierKey("accent_ring", "\u0056", FLAG_ACCENT_RING | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("accent_tilde", "\u0057", FLAG_ACCENT4 | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("accent_trema", "\u0058", FLAG_ACCENT6 | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("accent_ogonek", "\u0059", FLAG_ACCENT_OGONEK | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("accent_dot_above", "\u005a", FLAG_ACCENT_DOT_ABOVE | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("accent_double_aigu", "\u005b", FLAG_ACCENT_DOUBLE_AIGU | FLAG_KEY_FONT | FLAG_LOCALIZED);
addModifierKey("superscript", "Sup", FLAG_ACCENT_SUPERSCRIPT | FLAG_SMALLER_FONT);
addModifierKey("subscript", "Sub", FLAG_ACCENT_SUBSCRIPT | FLAG_SMALLER_FONT);
addModifierKey("ordinal", "Ord", FLAG_ACCENT_ORDINAL | FLAG_SMALLER_FONT);

View File

@@ -20,6 +20,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.util.Log;
import android.util.LogPrinter;
import java.util.Arrays;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
@@ -62,7 +63,7 @@ public class Keyboard2 extends InputMethodService
for (InputMethodInfo imi : imm.getEnabledInputMethodList())
if (imi.getPackageName().equals(pkg))
return imm.getEnabledInputMethodSubtypeList(imi, true);
return null;
return Arrays.asList();
}
private void refreshSubtypeLayout(InputMethodSubtype subtype)

View File

@@ -67,33 +67,33 @@ public class Keyboard2View extends View
invalidate();
}
public KeyValue onPointerDown(KeyValue k)
public KeyValue onPointerDown(KeyValue k, int flags)
{
k = KeyModifier.handleFlags(k, _flags);
k = KeyModifier.handleFlags(k, flags);
invalidate();
if (k != null)
vibrate();
return k;
}
public KeyValue onPointerSwipe(KeyValue k)
public KeyValue onPointerSwipe(KeyValue k, int flags)
{
k = KeyModifier.handleFlags(k, _flags);
k = KeyModifier.handleFlags(k, flags);
invalidate();
if (k != null)
vibrate();
return k;
}
public void onPointerUp(KeyValue k)
public void onPointerUp(KeyValue k, int flags)
{
_config.handler.handleKeyUp(k, _flags);
_config.handler.handleKeyUp(k, flags);
invalidate();
}
public void onPointerHold(KeyValue k)
public void onPointerHold(KeyValue k, int flags)
{
_config.handler.handleKeyUp(k, _flags);
_config.handler.handleKeyUp(k, flags);
}
public void onPointerFlagsChanged()

View File

@@ -23,10 +23,19 @@ public final class Pointers implements Handler.Callback
}
public int getFlags()
{
return getFlags(false);
}
/* When [skip_latched] is true, don't take flags of latched keys into account. */
private int getFlags(boolean skip_latched)
{
int flags = 0;
for (Pointer p : _ptrs)
flags |= p.flags;
{
if (!(skip_latched && p.pointerId == -1 && (p.flags & KeyValue.FLAG_LOCKED) == 0))
flags |= p.flags;
}
return flags;
}
@@ -52,7 +61,8 @@ public final class Pointers implements Handler.Callback
*/
public int getKeyFlags(KeyValue kv)
{
// Use physical equality because the key might have been modified.
// Comparing names because the keys might have been modified.
// Physical equality works because names are never computed or shared.
String name = kv.name;
for (Pointer p : _ptrs)
if (p.value != null && p.value.name == name)
@@ -80,7 +90,7 @@ public final class Pointers implements Handler.Callback
else // Otherwise, unlatch
{
removePtr(latched);
_handler.onPointerUp(ptr.value);
_handler.onPointerUp(ptr.value, ptr.modifier_flags);
}
}
else if ((ptr.flags & KeyValue.FLAG_LATCH) != 0)
@@ -93,7 +103,7 @@ public final class Pointers implements Handler.Callback
{
clearLatched();
removePtr(ptr);
_handler.onPointerUp(ptr.value);
_handler.onPointerUp(ptr.value, ptr.modifier_flags);
}
}
@@ -107,6 +117,15 @@ public final class Pointers implements Handler.Callback
_handler.onPointerFlagsChanged();
}
/* Whether an other pointer is down on a non-special key. */
private boolean isOtherPointerDown()
{
for (Pointer p : _ptrs)
if (p.pointerId != -1 && (p.flags & KeyValue.FLAG_SPECIAL) == 0)
return true;
return false;
}
public void onTouchDown(float x, float y, int pointerId, KeyboardData.Key key)
{
// Ignore new presses while a modulated key is active. On some devices,
@@ -114,10 +133,11 @@ public final class Pointers implements Handler.Callback
// keys.
if (isModulatedKeyPressed())
return;
KeyValue value = _handler.onPointerDown(key.key0);
Pointer ptr = new Pointer(pointerId, key, 0, value, x, y);
int mflags = getFlags(isOtherPointerDown());
KeyValue value = _handler.onPointerDown(key.key0, mflags);
Pointer ptr = new Pointer(pointerId, key, 0, value, x, y, mflags);
_ptrs.add(ptr);
if (value != null && (value.flags & KeyValue.FLAG_NOREPEAT) == 0)
if (value != null && (value.flags & KeyValue.FLAG_SPECIAL) == 0)
startKeyRepeat(ptr);
}
@@ -152,7 +172,8 @@ public final class Pointers implements Handler.Callback
if (newIndex != ptr.value_index)
{
ptr.value_index = newIndex;
KeyValue newValue = _handler.onPointerSwipe(ptr.key.getValue(newIndex));
KeyValue newValue =
_handler.onPointerSwipe(ptr.key.getValue(newIndex), ptr.modifier_flags);
if (newValue != null)
{
int old_flags = ptr.flags;
@@ -162,7 +183,7 @@ public final class Pointers implements Handler.Callback
if ((old_flags & newValue.flags & KeyValue.FLAG_PRECISE_REPEAT) == 0)
{
stopKeyRepeat(ptr);
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
if ((newValue.flags & KeyValue.FLAG_SPECIAL) == 0)
startKeyRepeat(ptr);
}
}
@@ -187,9 +208,11 @@ public final class Pointers implements Handler.Callback
private Pointer getLatched(Pointer target)
{
KeyboardData.Key k = target.key;
int vi = target.value_index;
KeyValue v = target.value;
if (v == null)
return null;
for (Pointer p : _ptrs)
if (p.key == k && p.value_index == vi && p.pointerId == -1)
if (p.key == k && p.pointerId == -1 && p.value != null && p.value.name == v.name)
return p;
return null;
}
@@ -237,7 +260,7 @@ public final class Pointers implements Handler.Callback
nextInterval = (long)((float)nextInterval / modulatePreciseRepeat(ptr));
}
_keyrepeat_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
_handler.onPointerHold(ptr.value);
_handler.onPointerHold(ptr.value, ptr.modifier_flags);
return (true);
}
}
@@ -290,13 +313,16 @@ public final class Pointers implements Handler.Callback
public float downY;
/** Distance of the pointer to the initial press. */
public float ptrDist;
/** Modifier flags at the time the key was pressed. */
public int modifier_flags;
/** Flags of the value. Latch, lock and locked flags are updated. */
public int flags;
/** Identify timeout messages. */
public int timeoutWhat;
/** ptrDist at the first repeat, -1 otherwise. */
public float repeatingPtrDist;
public Pointer(int p, KeyboardData.Key k, int vi, KeyValue v, float x, float y)
public Pointer(int p, KeyboardData.Key k, int vi, KeyValue v, float x, float y, int mflags)
{
pointerId = p;
key = k;
@@ -305,6 +331,7 @@ public final class Pointers implements Handler.Callback
downX = x;
downY = y;
ptrDist = 0.f;
modifier_flags = mflags;
flags = (v == null) ? 0 : v.flags;
timeoutWhat = -1;
repeatingPtrDist = -1.f;
@@ -315,19 +342,19 @@ public final class Pointers implements Handler.Callback
{
/** A key is pressed. Key can be modified or removed by returning [null].
[getFlags()] is not uptodate. */
public KeyValue onPointerDown(KeyValue k);
public KeyValue onPointerDown(KeyValue k, int flags);
/** Pointer swipes into a corner. Key can be modified or removed. */
public KeyValue onPointerSwipe(KeyValue k);
public KeyValue onPointerSwipe(KeyValue k, int flags);
/** Key is released. [k] is the key that was returned by [onPointerDown] or
[onPointerSwipe]. */
public void onPointerUp(KeyValue k);
public void onPointerUp(KeyValue k, int flags);
/** Flags changed because latched or locked keys or cancelled pointers. */
public void onPointerFlagsChanged();
/** Key is repeating. */
public void onPointerHold(KeyValue k);
public void onPointerHold(KeyValue k, int flags);
}
}

View File

@@ -1,12 +1,14 @@
<?xml version="1.0" standalone="no"?>
<!-- Accent from Roboto font family (Regular). Apache License, Version 2.0. -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-19 0 1167 2048">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-20 0 1168 2048">
<g transform="matrix(1 0 0 -1 0 1536)">
<path fill="currentColor"
d="M931 1003l-69 -70q-112 86 -250 99v99q176 -12 319 -128zM517 1032q-133 -10 -250 -101q0 1 -72 74l3 -2q143 116 319 128v-99zM198 860q-90 -103 -108 -246h-99q17 182 137 319l-6 6l4 -3l41 -43q31 -32 31 -33zM1138 614h-100q-17 141 -107 249l70 70
q120 -137 137 -319zM1138 518q-14 -190 -130 -327l-69 70q86 111 99 257h100zM190 264q-76 -77 -75 -77l4 4q-115 137 -128 327h99q14 -147 100 -254zM939 121q-146 -124 -327 -136v100q140 12 258 106zM517 -15q-180 12 -327 136l69 70q118 -90 258 -106v-100zM687 0
q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154q0 80 60.5 152t187.5 128z" />
d="M931.256 1002.78l-69.3145 -69.3145q-112.472 86.3154 -249.792 98.0859v99.3945q176.555 -11.7715 319.106 -128.166v0zM516.679 1031.55q-133.396 -10.4619 -249.792 -100.701q0 1.30859 -71.9297 74.5449l2.61523 -2.61523q142.554 116.396 319.106 128.166v-99.3945
v0zM197.572 860.229q-90.2393 -103.316 -107.24 -245.867h-99.3936q17.001 181.786 137.32 319.104l-6.53906 5.23145l3.92285 -2.61523l41.8506 -43.1582q30.0791 -31.3867 30.0791 -32.6953v0zM1137.89 614.361h-99.3936q-17.001 141.242 -107.239 248.483
l69.3135 70.6211q120.318 -137.319 137.319 -319.104v0zM1137.89 517.583q-14.3857 -189.633 -129.474 -326.953l-69.3135 70.6221q86.3154 111.164 99.3936 256.331h99.3936v0zM189.726 263.867h0.000976562q-86.3154 107.239 -99.3936 253.716h-99.3945
q13.0781 -189.633 128.165 -326.953l-3.92285 -3.92383q-1.30762 0 74.5449 77.1611zM939.103 121.315q-146.476 -124.242 -326.952 -136.014v99.3945q139.935 11.7705 257.639 105.934zM516.679 -14.6973q-180.478 11.7715 -326.953 136.013l69.3145 69.3145
q117.703 -90.2383 257.64 -105.933v-99.3945h-0.000976562zM623 -9l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57l-7 109q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

13
srcs/special_font/59.svg Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-20 0 1168 2048">
<g transform="matrix(1 0 0 -1 0 1536)">
<path fill="currentColor"
d="M931.256 1002.78l-69.3145 -69.3145q-112.472 86.3154 -249.792 98.0859v99.3945q176.555 -11.7715 319.106 -128.166v0zM516.679 1031.55q-133.396 -10.4619 -249.792 -100.701q0 1.30859 -71.9297 74.5449l2.61523 -2.61523q142.554 116.396 319.106 128.166v-99.3945
v0zM197.572 860.229q-90.2393 -103.316 -107.24 -245.867h-99.3936q17.001 181.786 137.32 319.104l-6.53906 5.23145l3.92285 -2.61523l41.8506 -43.1582q30.0791 -31.3867 30.0791 -32.6953v0zM1137.89 614.361h-99.3936q-17.001 141.242 -107.239 248.483
l69.3135 70.6211q120.318 -137.319 137.319 -319.104v0zM1137.89 517.583q-14.3857 -189.633 -129.474 -326.953l-69.3135 70.6221q86.3154 111.164 99.3936 256.331h99.3936v0zM189.726 263.867h0.000976562q-86.3154 107.239 -99.3936 253.716h-99.3945
q13.0781 -189.633 128.165 -326.953l-3.92285 -3.92383q-1.30762 0 74.5449 77.1611zM939.103 121.315q-146.476 -124.242 -326.952 -136.014v99.3945q139.935 11.7705 257.639 105.934zM516.679 -14.6973q-180.478 11.7715 -326.953 136.013l69.3145 69.3145
q117.703 -90.2383 257.64 -105.933v-99.3945h-0.000976562zM987 0q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154q0 80 60.5 152t187.5 128z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
srcs/special_font/5A.svg Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-20 0 1168 2048">
<g transform="matrix(1 0 0 -1 0 1536)">
<path fill="currentColor"
d="M931.256 1002.78l-69.3145 -69.3145q-112.472 86.3154 -249.792 98.0859v99.3945q176.555 -11.7715 319.106 -128.166v0zM516.679 1031.55q-133.396 -10.4619 -249.792 -100.701q0 1.30859 -71.9297 74.5449l2.61523 -2.61523q142.554 116.396 319.106 128.166v-99.3945
v0zM197.572 860.229q-90.2393 -103.316 -107.24 -245.867h-99.3936q17.001 181.786 137.32 319.104l-6.53906 5.23145l3.92285 -2.61523l41.8506 -43.1582q30.0791 -31.3867 30.0791 -32.6953v0zM1137.89 614.361h-99.3936q-17.001 141.242 -107.239 248.483
l69.3135 70.6211q120.318 -137.319 137.319 -319.104v0zM1137.89 517.583q-14.3857 -189.633 -129.474 -326.953l-69.3135 70.6221q86.3154 111.164 99.3936 256.331h99.3936v0zM189.726 263.867h0.000976562q-86.3154 107.239 -99.3936 253.716h-99.3945
q13.0781 -189.633 128.165 -326.953l-3.92285 -3.92383q-1.30762 0 74.5449 77.1611zM939.103 121.315q-146.476 -124.242 -326.952 -136.014v99.3945q139.935 11.7705 257.639 105.934zM516.679 -14.6973q-180.478 11.7715 -326.953 136.013l69.3145 69.3145
q117.703 -90.2383 257.64 -105.933v-99.3945h-0.000976562zM648 1283h-218v201h218v-201z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

13
srcs/special_font/5B.svg Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-20 0 1184 2048">
<g transform="matrix(1 0 0 -1 0 1536)">
<path fill="currentColor"
d="M931.256 1002.78l-69.3145 -69.3145q-112.472 86.3154 -249.792 98.0859v99.3945q176.555 -11.7715 319.106 -128.166v0zM516.679 1031.55q-133.396 -10.4619 -249.792 -100.701q0 1.30859 -71.9297 74.5449l2.61523 -2.61523q142.554 116.396 319.106 128.166v-99.3945
v0zM197.572 860.229q-90.2393 -103.316 -107.24 -245.867h-99.3936q17.001 181.786 137.32 319.104l-6.53906 5.23145l3.92285 -2.61523l41.8506 -43.1582q30.0791 -31.3867 30.0791 -32.6953v0zM1137.89 614.361h-99.3936q-17.001 141.242 -107.239 248.483
l69.3135 70.6211q120.318 -137.319 137.319 -319.104v0zM1137.89 517.583q-14.3857 -189.633 -129.474 -326.953l-69.3135 70.6221q86.3154 111.164 99.3936 256.331h99.3936v0zM189.726 263.867h0.000976562q-86.3154 107.239 -99.3936 253.716h-99.3945
q13.0781 -189.633 128.165 -326.953l-3.92285 -3.92383q-1.30762 0 74.5449 77.1611zM939.103 121.315q-146.476 -124.242 -326.952 -136.014v99.3945q139.935 11.7705 257.639 105.934zM516.679 -14.6973q-180.478 11.7715 -326.953 136.013l69.3145 69.3145
q117.703 -90.2383 257.64 -105.933v-99.3945h-0.000976562zM856 1545h229l3 -6l-300 -260h-171l-2 5zM530 1545h211l2 -5l-240 -261h-157z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -3,7 +3,7 @@
New()
# Imports glyphs, file name is position in the font.
i = 2
i = 1
while (i < $argc)
Select(Strtol($argv[i]:t:r, 16))
Import($argv[i], 0, 0, 4.0, 0.1)
@@ -11,4 +11,4 @@ while (i < $argc)
i++
endloop
Generate($1)
Generate("result.ttf")

Binary file not shown.