AWTK T9 输入法实现原理

news2024/11/15 12:07:10

在这里插入图片描述
在这里插入图片描述

1. T9 输入法的中文字典数据

网上可以找到 T9 输入法的中文字典数据,但是通常有两个问题:

  • 采用 GPL 协议,不太适合加入 AWTK。

  • 只支持单个汉字的输入,不支持词组的输入。

经过考虑之后,决定自己生成 T9 输入法的中文字典数据。AWTK 使用了谷歌拼音输入法作为缺省的拼音输入法,谷歌拼音输入法的字典数据质量还是不错的,写一个工具把谷歌拼音输入法的字典数据转换为 T9 输入法的中文字典数据即可。

谷歌拼音输入法的字典数据原始格式为:

汉字 频率 简体/繁体标志 拼音

如:

中 243213.912993 0 zhong

转换工具要做的事情的是:

  • 把拼音转换成对应的数字。比 zhong 对应的是 83553。

  • 生成适合查询的格式。本来想复用谷歌拼音输入的引擎,但是没有成功,最后决定自己写程序来查询。

转换工具完整的代码请参考:awtk/tools/t9_gen/to_t9_zh.js

如果需要对字典进行裁剪,可以先编辑原始数据,然后重新生成数据。

2. T9 输入法的英文字典数据

要生成英文字典数据,获取一个英文单词列表,并且按照单词的使用频率进行排序。找 github 上找到了这样的数据。

同样需要写个小工具,把该数据转成生成适合查询的格式。

转换工具完整的代码请参考:awtk/tools/t9_gen/to_t9_en.js

该工具应该同样适用于其它西文语言。

3. 对键盘、输入法框架和编辑器进行改进

为了支持 T9 输入法,需要对键盘、输入法框架和编辑器进行改进。

随便提一下,SOLID 原则中的开闭原则通常只存在于理想(简单)情况下,一种切实可行的方法是,在早期设计时要考虑将来的扩展,但也无需过度设计,而是每次扩展时都对框架进行完善,让它更适应于将来的扩展。

3.1 支持语言切换

同样是在中文环境下,你可能需要输入中文,也可能需要输入英文。在中文键盘下输入中文,在英文键盘下输入英文。 在键盘切换时需要让输入法引擎知道当前的语言。

3.1.1 键盘

如果需要切换语言,可以给键盘的页面设置一个 lang 属性,用于标识改键盘的语言,切换到该页面时,自动设置输入法引擎的语言。

如:

    <view name="chinese" lang="zh_cn" 
      x="0" y="0" w="100%" h="100%" children_layout="default(r=4,c=4,s=2,m=2)">
        <button repeat="300" name="" text=""/>
        <button repeat="300" name="key:1" text="ABC"/>
        <button repeat="300" name="key:2" text="DEF"/>
        <button repeat="300" name="key:backspace" style="highlight">
          <image draw_type="icon" image="backspace" x="center" y="middle" w="100%" h="100%"/>
        </button>
        <button repeat="300" name="key:3" text="GHI"/>
        <button repeat="300" name="key:4" text="JKL"/>
        <button repeat="300" name="key:5" text="MNO"/>
        <button name="page:lower" style="highlight" text="abc"/>

        <button repeat="300" name="key:6" text="PQRS"/>
        <button repeat="300" name="key:7" text="TUV"/>
        <button repeat="300" name="key:8" text="WXYZ"/>
        <button name="page:symbols" style="highlight" text="#+="/>
        <button repeat="300" name="opt:。?!" text="。?!"/>
        <button repeat="300" name="space" text="Space"/>
        <button name="action" style="highlight" text="Return"/>
        <button name="page:number" style="highlight" text="123"/>
    </view>

在切换键盘时,如果存在 lang 属性,将其设置到输入法。

    value_t v;
    widget_t* active = widget_get_child(iter, widget_get_value(iter));

    if (widget_get_prop(active, WIDGET_PROP_IM_LANG, &v) == RET_OK) {
      input_method_set_lang(input_method(), value_str(&v));
    }
3.1.2 输入法提供设置语言的函数
/**
 * @method input_method_set_lang
 * 设置语言。
 *
 * > 有的输入法,同时支持输入多种语言。
 * > 比如 T9,可以同时支持中文和英文输入,配合软键盘随时切换输入的语言。
 *
 * @annotation ["scriptable"]
 * @param {input_method_t*} im 输入法对象。
 * @param {const char*} lang 语言。
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t input_method_set_lang(input_method_t* im, const char* lang);
3.1.3 输入法引擎提供设置语言的函数
/**
 * @engine input_engine_set_lang
 * 设置语言。
 * @annotation ["scriptable"]
 * @param {input_engine_t*} engine 输入法引擎对象。
 * @param {const char*} lang 语言。
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t input_engine_set_lang(input_engine_t* engine, const char* lang);

3.2 支持预编辑状态 (preedit)

预编辑状态是在文本真正提交到编辑器之前的状态,在预编辑状态下输入的文本,可以被后面的输入覆盖。比如软键盘上,一个按键有 ABC 三个字符,按一下输入 A,再按一下输入 B,继续按钮输入 C,在指定时间内没有按,则提交当前的字符到编辑器。

在这里插入图片描述

3.2.1 软键盘

键盘的按钮名称以"opt:"开头的按钮,表示这个按钮需要预编辑处理。为了支持预编辑输入,软键盘在按钮事件处理函数中,要做下列处理:

  • 当前不在预编辑状态时,则进入预编辑状态,并启动定时器,把当前字符的序数设置为 0,并提交字符到编辑器。

  • 当前在预编辑状态,更新定时器,把字符的序数设置为下一个,并提交字符到编辑器。

  • 定时器超时或点击其它按钮,退出预编辑。

详情参考函数:keyboard_on_button_click

3.2.2 输入法

输入法需要提供几个函数用于中转消息:

/**
 * @method input_method_dispatch_preedit
 * 分发进入预编辑状态的事件。
 * @annotation ["scriptable"]
 * @param {input_method_t*} im 输入法对象。
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t input_method_dispatch_preedit(input_method_t* im);

/**
 * @method input_method_dispatch_preedit_confirm
 * 分发确认预编辑状态的事件(提交预编辑内容,退出预编辑状态)。
 * @annotation ["scriptable"]
 * @param {input_method_t*} im 输入法对象。
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t input_method_dispatch_preedit_confirm(input_method_t* im);

/**
 * @method input_method_dispatch_preedit_abort
 * 分发取消预编辑状态的事件(提交预编辑内容,退出预编辑状态)。
 * @annotation ["scriptable"]
 * @param {input_method_t*} im 输入法对象。
 *
 * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
 */
ret_t input_method_dispatch_preedit_abort(input_method_t* im);

3.2.3 编辑器

编辑器需要处理相关事件:

    case EVT_IM_PREEDIT: {
      text_edit_preedit(edit->model);
      break;
    }
    case EVT_IM_PREEDIT_CONFIRM: {
      text_edit_preedit_confirm(edit->model);
      break;
    }
    case EVT_IM_PREEDIT_ABORT: {
      text_edit_preedit_abort(edit->model);
      break;
    }

具体请参考:edit.c/mledit.c

4. T9 输入法引擎的实现

T9 输入法引擎的实现很简单,不到 300 行代码。查找算法为:先精确查找,如果找到,将其添加到候选字列表中,否则使用前缀查找,在满足前缀的候选字中,挑选词频最高的,放到候选字列表中。

详情参考:input_engine_t9.c/t9.c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1542716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024,淘天六大升级,电商人都准备好了吗?|淘天商品数据采集商品订单接口

淘天各类商品API接口 许多商家一直在问&#xff0c;到了2024年&#xff0c;淘天到底有哪些新改变&#xff1f;商家们又该如何做优化、调整&#xff1f; 我们总结来看&#xff0c;主要在六个方面进行了升级。 第一个是流量获取的逻辑变了。 从曾经的单一的流量入口&#xff0c;…

Leetcode——560. 和为 K 的子数组

560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/subarray-sum-equals-k/description/ 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回该数组中和为 k 的子数组的个数 。子数组是数组中元素…

Ubuntu学习笔记之Shell与APT下载工具

基本都是摘抄正点原子的文章&#xff1a;<领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 一、Ubuntu Shell操作 简单的说Shell 就是敲命令。国内把 Linux 下通过命令行输入命令叫…

福昕阅读器 PDF 文档基本操作

福昕阅读器 PDF 文档基本操作 References 转至 PDF 顶部 快捷键&#xff1a;Home. 转至 PDF 顶部 快捷键&#xff1a;End. 打开超链接 文本选择工具 -> 手形工具 (Hand Tool) -> 点击超链接 福昕阅读器 同时在多个窗口中打开多个文件 文件 -> 偏好设置 -> 文…

Autosar-WdgM配置详解(免费)-2

1.4生成Wdg模块以及代码 按以下步骤生成WdgM模块代码&#xff1a; 工具如果成功生成的话&#xff0c;会在COmponnets下面创建一个WdgM的SWC&#xff0c;如下图: 1.5创建SWC模块 WdgM已经提供了deadline的port&#xff0c;接下来就是需要SWC使用WdgM的port。 1.5.1创建Master…

目标检测中的mAP计算原理和源码实现

简介 在目标检测任务中&#xff0c;mAP&#xff08;mean Average Precision&#xff0c;平均精度均值&#xff09;是一个非常重要的评价指标&#xff0c;用于衡量模型在多个类别上的平均性能。它综合考虑了模型在不同召回率下的精确率&#xff0c;能够全面反映模型在检测任务中…

Python从0到100(七):Python列表介绍及运用

一、 列表概述 问题描述&#xff1a; 假设一个班有100个学生&#xff0c;如果每个变量存放一个学生的姓名&#xff0c;是不是很麻烦&#xff1f;如果有一千个学生甚至更多&#xff0c;那该怎么办呢&#xff1f; 列表是Python中的一种数据结构&#xff0c;它可以存储不同类型的…

冰蓄冷空调的工作原理介绍

冰蓄冷空调(Ice Storage Air Conditioning System)是一种利用夜间电力低谷时段储存冷量,白天用电高峰时段释放冷量的空调技术。 这种技术通过在电网负荷低谷时(如深夜)运行制冷设备,将电能转化为冷量储存在冰块或者冷冻水中,然后在白天电网负荷高峰时,将储存的冷量释放…

电脑怎么卸载软件?分享3个正确操作方法!

“我电脑上下载了很多的软件&#xff0c;这些软件很多我都不需要了&#xff0c;有什么方法可以安全卸载它们吗&#xff1f;” 随着我们使用电脑的时间越来越长&#xff0c;安装的软件也越来越多。但有时候&#xff0c;我们会因为某些原因需要卸载一些软件&#xff0c;以释放硬盘…

美团offer啦

我爱团子&#xff0c;真得叫团爹吧&#xff01; 3.16笔试 3.19一面 3.20二面➕oc 3.21 offer 只能说进度有点太快了&#xff0c;直接开摆吧&#xff0c;终于可以歇一歇了。 把好运传给大家&#xff0c;祝大家都能找到心仪的offer。 #美团# 作者&#xff1a;洛杉矶快船保罗乔治

javaSwing宿舍管理系统(三个角色)

一、 简介 宿舍管理系统是一个针对学校宿舍管理的软件系统&#xff0c;旨在方便学生、宿管和管理员进行宿舍信息管理、学生信息管理以及宿舍评比等操作。该系统使用 Java Swing 进行界面设计&#xff0c;分为三个角色&#xff1a;管理员、宿管和学生。 二、 功能模块 2.1 管…

STM32微控制器的中断优先级设置中,抢占优先级和子优先级如何影响中断响应?

在STM32微控制器中&#xff0c;中断优先级设置是一个关键的概念&#xff0c;它决定了在发生多个中断时&#xff0c;哪些中断能够优先被处理。STM32的中断优先级系统包括抢占优先级&#xff08;Preemption Priority&#xff09;和子优先级&#xff08;Subpriority&#xff09;&a…

Java22已发布,支持SpringBoot3.3.0正式版

Java22已发布&#xff0c;支持SpringBoot3.3.0正式版 文章目录 Java22已发布&#xff0c;支持SpringBoot3.3.0正式版1. JDK22现已推出&#xff01;2. Java22的新功能1. 语言改进1. 语言预览 2. 库文件3. 性能4. 工具 3. 资源 Java 22现已发布 下一个Java版本提高了Java应用程序…

使用pandas进行数据清洗

采集到原始的数据中会存在一些噪点数据&#xff0c;噪点数据是对分析无意义或者对分析起到偏执作用的数据。如何清洗&#xff1a; 清洗空值/缺失值清洗重复值清洗异常值 import pandas as pd from pandas import DataFrame,Series import numpy as np pandas处理空值操作 i…

EasyPOI操作Excel从零入门

教程介绍 我们不造轮子&#xff0c;只是轮子的搬运工。&#xff08;其实最好是造轮子&#xff0c;造比别人好的轮子&#xff09;开发中经常会遇到excel的处理&#xff0c;导入导出解析等等&#xff0c;java中比较流行的用poi&#xff0c;但是每次都要写大段工具类来搞定这事儿…

Python6:Socket编程初步学习笔记

Socket协议概要 创建socket的时候&#xff0c;需要一些选项来说明本次使用协议具体是什么&#xff0c;常用的两个&#xff1a; 由此产生的不同组合&#xff1a; 但目前TCP(IPV4)是主流&#xff0c;SOCK_STREAMAF_INET 创建和使用Socket socket模块中有socket类&#xff1a…

macOS访问samba文件夹的正确姿势,在哪里更改“macOS的连接身份“?还真不好找!

环境&#xff1a;路由器上需要身份认证的Mini NAS macOS Sonoma 14 这是一个非常简单的问题&#xff0c;但解决方法却藏得比较深&#xff0c;不够直观&#xff0c;GPT也没有给出明确的解决提示&#xff0c;特意记录一下。 macOS很多地方都很自动&#xff0c;有时候让人找不到设…

深度学习pytorch——多分类问题(持续更新)

回归问题 vs 分类问题&#xff08;regression vs classification&#xff09; 回归问题&#xff08;regression&#xff09; 1、回归问题的目标是使预测值等于真实值&#xff0c;即predy。 2、求解回归问题的方法是使预测值和真实值的误差最小&#xff0c;即minimize dist(p…

opencv各个模块介绍(2)

Features2D 模块&#xff1a;特征检测和描述子计算模块&#xff0c;包括SIFT、SURF等算法。 Features2D 模块提供了许多用于特征检测和描述子匹配的函数和类&#xff0c;这些函数和类可用于图像特征的提取、匹配和跟踪。 FeatureDetector&#xff1a;特征检测器的基类&#xf…

java数据结构与算法刷题-----LeetCode452. 用最少数量的箭引爆气球

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路&#xff1a;贪心算法&#xff0c;时间复杂度O( n ∗ l …