AWTK T9 输入法实现原理

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

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.mzph.cn/news/767368.shtml

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

相关文章

Mamba复现与代码解读

文章目录 环境配置demo推理源码解析参数解读Mamba块&#xff08;Mamba Block&#xff09;状态空间模型(SSM)选择性扫描算法&#xff08;selective_scan&#xff09;前向传播&#xff08;forward&#xff09; 均方根归一化 &#xff08;RMSNorm&#xff09;残差块&#xff08;Re…

集成学习 | 集成学习思想:Boosting

目录 一. Boosting思想1. Adaboost 算法1.1 Adaboost算法构建流程1.2 sklearn库参数说明 2. Gradient Boosting 算法2.1 Gradient Boosting算法构建流程2.2 Gradient Boosting算法的回归与分类问题2.2.1 Gradient Boosting回归算法均方差损失函数绝对误差损失函数 2.2.2 Gradie…

【Linux】进程地址空间详解

前言 在我们学习C语言或者C时肯定都听过老师讲过地址的概念而且老师肯定还会讲栈区、堆区等区域的概念&#xff0c;那么这个地址是指的物理内存地址吗&#xff1f;这里这些区域又是如何划分的呢&#xff1f; 我们在使用C语言的malloc或者C的new函数开辟空间时&#xff0c;开辟…

解锁隐私计算力量:一站式掌握SecretFlow安装与双模式部署实践

1.SecretFlow的安装 1.SecretFlow运行要求 SecretFlow作为一个隐私保护的数据分析和机器学习框架&#xff0c;其运行要求可能涉及以下方面&#xff1a; 操作系统&#xff1a; 能够支持Docker运行的环境&#xff0c;因为SecretFlow可能通过Docker容器来管理执行环境的一致性和…

Python Flask 自定义404错误

from flask import Flask, abort, make_response, request, render_templateapp Flask(__name__)# 重定向到百度 app.route(/index, methods["GET", "POST"]) def index():if request.method "GET":return render_template("index.html&q…

推荐一款制造执行系统(MES)国内比较好的实施厂家

什么是MES 制造执行系统&#xff08;MES&#xff09;是一种用于监控、控制和优化制造过程的软件系统。它通过与企业资源计划&#xff08;ERP&#xff09;系统和自动化系统的集成&#xff0c;实现对生产过程的管理和监测&#xff0c;包括生产计划、生产过程和生产数据。 MES可…

BUG未解之谜01-指针引用之谜

在leetcode里面刷题出现的问题&#xff0c;当我在sortedArrayToBST里面给root赋予初始值NULL之后&#xff0c;问题得到解决&#xff01; 理论上root是未初始化的变量&#xff0c;然后我进入insert函数之后&#xff0c;root引用的内容也是未知值&#xff0c;因此无法给原来的二叉…

鸿蒙开发学习【地图位置服务组件】

简介 移动终端设备已经深入人们日常生活的方方面面&#xff0c;如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动&#xff0c;都离不开定位用户终端设备的位置。 当用户处于这些丰富的使用场景中时&#xff0c;系统的位置定位能力可以提供…

【Python】基础语法(一)

文章目录 1.注释2.关键字与标识符2.1关键字2.2标识符 3.变量4.数据类型4.1数字类型4.2类型转换函数4.3布尔类型 5.输入(input)与输出(print)5.1输入函数(input)5.2输出函数(print) 6.运算符6.1算术运算符6.2比较运算符6.3赋值运算符6.4逻辑运算符6.5运算符优先级 7.字符串7.1字…

JMH微基准测试框架学习笔记

一、简介 JMH&#xff08;Java Microbenchmark Harness&#xff09;是一个用于编写、构建和运行Java微基准测试的框架。它提供了丰富的注解和工具&#xff0c;用于精确控制测试的执行和结果测量&#xff0c;从而帮助我们深入了解代码的性能特性。 二、案例实战 在你的pom文件…

MySQL 排序的那些事儿

书接上回 上次发了几张图&#xff0c;给了几个MySQL Explain的场景&#xff0c;链接在这儿&#xff1a;你是不是MySQL老司机&#xff1f;来看看这些explain结果你能解释吗&#xff1f;MySQL 夺命6连问 我们依次来分析下这6个问题。 在分析之前&#xff0c;我们先来了解一下M…

操作系统面经-用户态和内核态

字节实习生带你面试&#xff0c;后台私信可以获得面试必过大法&#xff01;&#xff01; 根据进程访问资源的特点&#xff0c;我们可以把进程在系统上的运行分为两个级别&#xff1a; 用户态(User Mode) : 用户态运行的进程可以直接读取用户程序的数据&#xff0c;拥有较低的…

【蓝牙协议栈】【BLE】低功耗蓝牙配对绑定过程分析(超详细)

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待&#xff01…

Three.js 中的 OrbitControls 是一个用于控制相机围绕目标旋转以及缩放、平移等操作的控制器。

demo案例 Three.js 中的 OrbitControls 是一个用于控制相机围绕目标旋转以及缩放、平移等操作的控制器。下面是它的详细讲解&#xff1a; 构造函数: OrbitControls(object: Camera, domElement?: HTMLElement)object&#xff1a;THREE.Camera 实例&#xff0c;控制器将围绕…

从零开始学习在VUE3中使用canvas(五):globalCompositeOperation(图形混合)

一、简介 通过设置混合模式来改变图像重叠区域的显示方式。 const ctx canvas.getContext("2d");ctx.globalCompositeOperation "source-over"; 二、属性介绍 source-over 这是默认的复合操作。将源图像绘制到目标图像上&#xff0c;保留目标图像的不透…

IPV6协议之DHCPV6

目录 背景&#xff1a; 一、DHCPV6概述 DHCPv6 Client&#xff1a; DHCPv6 Relay&#xff1a; DHCPv6 Server&#xff1a; 二、DHCPV6工作原理 DHCPV6无状态自动分配 三、DHCP基础配置 服务端 四、DHCPV6地址更新时间&#xff08;DHCPV4租期&#xff09; 五、DHCPV6…

idea 开发serlvet篮球秩序册管理系统idea开发mysql数据库web结构计算机java编程layUI框架开发

一、源码特点 idea开发 java servlet 篮球秩序册管理系统是一套完善的web设计系统mysql数据库 系统采用serlvetdaobean mvc 模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 servlet 篮…

☆【前后缀】【双指针】Leetcode 42. 接雨水

【前后缀】【双指针】Leetcode 42. 接雨水 解法1 前后缀分解解法2 双指针 ---------------&#x1f388;&#x1f388;42. 接雨水 题目链接&#x1f388;&#x1f388;------------------- 解法1 前后缀分解 维护一个前缀&#xff08;左侧最高&#xff09;后缀&#xff08;右侧…

【Linux系统编程(进程编程)】进程的退出:父进程等待子进程的退出之僵尸进程与孤儿进程

文章目录 一、进程退出1.1、进程正常退出方式1.2、异常退出 二、父进程等待子进程退出&#xff08;一&#xff09;2.1、为什么要等待子进程退出2.2、&#xff08;1&#xff09;父进程等待子进程退出并收集子进程的退出状态如何等待wstatus空wstatus非空 2.3、&#xff08;2&…

LeetCode---389周赛

题目列表 3083. 字符串及其反转中是否存在同一子字符串 3084. 统计以给定字符开头和结尾的子字符串总数 3085. 成为 K 特殊字符串需要删除的最少字符数 3086. 拾起 K 个 1 需要的最少行动次数 一、字符串及其反转中是否存在同一子字符串 直接暴力枚举即可&#xff0c;代码…