直接辅助码的四码在句中原来只能补 / 结束(uiab/),现在也可以把第二位辅码敲成大写(uiaB)。 设置页「直接辅助码句中四码标记」两个勾选框可多选、至少留一个,默认只勾 /。 - 引擎:拼写图新增 Aux2Upper(非缩写)。开着大写标记时大写字母只能当第二位辅码, 走不通再退回不分大小写的旧规则,第一位辅码敲大写(uiAuiQ)照常可用。/ 的收键受勾选控制。 - 协议:DirectHelpcodeChanged 载荷改为 "0"/"1"/"2"(2 = 开着但 / 不是编码键), TSF 据此决定吃不吃 /。 - 配置:新增 helpcode.shuangpin_direct_helpcode_slash / _uppercase,同步写入出厂模板、 工作配置和两个设置宿主的读写映射。
67 lines
3.0 KiB
C++
67 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
|
|
// 双拼直接辅助码(万象式,规则见 engine/direct_helpcode/spelling_graph.h)的按键形状。
|
|
//
|
|
// 直接辅助码不要引导键:辅码字母就是普通字母键,TSF 本来就吃。要额外判断的只有两个键:
|
|
//
|
|
// / 四码(双拼 + 两位辅码)后面的终止键:uiab/。不当编码键时它是「上屏高亮候选 + /」。
|
|
// ; 微软/搜狗等双拼的 ing 韵母。平时按「所在一节是奇数键」判断,可辅码会打乱奇偶(uia 后面
|
|
// 接 x; 时这一节是偶数键),开着直接辅助码时改成只看前一个键是不是字母。
|
|
//
|
|
// TSF 在同步吃键阶段先判断,Server 随后按同一条规则决定收不收、引擎按它解析。三处必须一致,否则
|
|
// 两边的输入串会分叉。TSF 不链接引擎、没有音节表,所以这里只看形状,/ 到底凑不凑得成四码由引擎
|
|
// 判断,凑不成时引擎把它当分隔符处理,不会让整串作废。
|
|
//
|
|
// 四码也可以用第二位辅码大写来结束(uiaB,设置里和 / 各一个勾)。大写字母本来就是编码键,TSF 不用
|
|
// 另外判断;但 / 没勾时 TSF 不能再吃它,所以 DirectHelpcodeChanged 的载荷要带上 / 勾没勾。
|
|
namespace FanyImeDirectHelpcode
|
|
{
|
|
inline constexpr char kSlash = '/';
|
|
|
|
// DirectHelpcodeChanged 的载荷(一个字符):"0" 关,"1" 开且 / 是四码的终止键,"2" 开但 / 不是编码键。
|
|
inline constexpr wchar_t PayloadFor(bool enabled, bool slash)
|
|
{
|
|
return !enabled ? L'0' : slash ? L'1' : L'2';
|
|
}
|
|
|
|
inline constexpr bool IsValidPayload(wchar_t payload)
|
|
{
|
|
return payload == L'0' || payload == L'1' || payload == L'2';
|
|
}
|
|
|
|
inline constexpr bool EnabledFromPayload(wchar_t payload)
|
|
{
|
|
return payload == L'1' || payload == L'2';
|
|
}
|
|
|
|
inline constexpr bool SlashFromPayload(wchar_t payload)
|
|
{
|
|
return payload == L'1';
|
|
}
|
|
|
|
template <typename Char> constexpr bool IsAsciiLetter(Char ch)
|
|
{
|
|
return (ch >= Char('a') && ch <= Char('z')) || (ch >= Char('A') && ch <= Char('Z'));
|
|
}
|
|
|
|
// 光标停在 text[caret] 时能否插入 /:光标前是「两键音节 + 两个辅码字母」的形状(音节第二键可以
|
|
// 是 ; 韵母),且光标后不是已经有一个 /。
|
|
template <typename Char> constexpr bool AcceptsSlashAt(const Char *text, std::size_t size, std::size_t caret)
|
|
{
|
|
if (caret < 4 || caret > size || (caret < size && text[caret] == Char(kSlash)))
|
|
{
|
|
return false;
|
|
}
|
|
return IsAsciiLetter(text[caret - 1]) && IsAsciiLetter(text[caret - 2]) &&
|
|
(IsAsciiLetter(text[caret - 3]) || text[caret - 3] == Char(';')) && IsAsciiLetter(text[caret - 4]);
|
|
}
|
|
|
|
// 光标停在 text[caret] 时 ; 能否作为 ing 韵母(只对用 ; 当韵母的双拼方案有意义)。
|
|
template <typename Char> constexpr bool AcceptsSemicolonFinalAt(const Char *text, std::size_t size, std::size_t caret)
|
|
{
|
|
return caret >= 1 && caret <= size && IsAsciiLetter(text[caret - 1]);
|
|
}
|
|
} // namespace FanyImeDirectHelpcode
|