日语模式下把 - 让给长音符(ー)输入,同时禁掉 -/= 的候选翻页: - 罗马字方案接受 VK_OEM_MINUS,set_raw_input 不再把 - 过滤掉; 罗马字表里本来就有 - 到 ー 的条目,只缺按键准入。 - n 后面接 - 时按辅音处理,让前面的 n 收成 ん,避免 n- 卡在 pending。 - 空编码时单独按 - 也起头组合,候选框第一项是 ー、第二项是普通 -。 - 组词流程同样适用:判据只看日语模式加组合状态,不再走翻页和词转字。 - -/= 在日语模式下不翻页,_ = + 这些没有假名写法的字符退回标点上屏, 并把 = _ 补进服务端的标点集合,和 TSF 侧保持一致,否则会等不到回包。 TSF 侧的影子分类、IsVirtualKeyNeed(ForFreshComposition) 和服务端按键策略 三处同时改,统一以配置项 input_mode == japanese 为判据(R 模式不在范围内, TSF 侧看不到临时会话,用会话类型判断会让两侧分类打架)。
94 lines
2.9 KiB
C++
94 lines
2.9 KiB
C++
#include "japanese_romaji_scheme.h"
|
|
#include "../japanese/romaji_converter.h"
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
namespace
|
|
{
|
|
bool IsRomajiKey(ImeKeyCode vk)
|
|
{
|
|
return vk >= 'A' && vk <= 'Z';
|
|
}
|
|
} // namespace
|
|
|
|
void JapaneseRomajiScheme::reset()
|
|
{
|
|
raw_input_.clear();
|
|
key_strokes_.clear();
|
|
}
|
|
|
|
void JapaneseRomajiScheme::handle_key(ImeKeyCode vk, ImeModifierMask modifiers_down, ImeCharacter wch)
|
|
{
|
|
if (vk == ImeKey::Backspace)
|
|
{
|
|
if (!raw_input_.empty())
|
|
raw_input_.pop_back();
|
|
if (!key_strokes_.empty())
|
|
key_strokes_.pop_back();
|
|
return;
|
|
}
|
|
if (vk == ImeKey::Escape || vk == ImeKey::Return)
|
|
{
|
|
reset();
|
|
return;
|
|
}
|
|
if (vk == ImeKey::Apostrophe && wch == u'\'')
|
|
{
|
|
raw_input_.push_back('\'');
|
|
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
|
|
return;
|
|
}
|
|
// '-' 是长音符(ー)的罗马字写法,不是翻页键,罗马字表里已有对应条目。
|
|
if (vk == ImeKey::Minus && wch == u'-')
|
|
{
|
|
raw_input_.push_back('-');
|
|
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
|
|
return;
|
|
}
|
|
if (!IsRomajiKey(vk))
|
|
return;
|
|
|
|
key_strokes_.push_back(KeyStroke{vk, modifiers_down, wch});
|
|
if ((wch >= u'a' && wch <= u'z') || (wch >= u'A' && wch <= u'Z'))
|
|
raw_input_.push_back(static_cast<char>(wch));
|
|
else
|
|
raw_input_.push_back(static_cast<char>(vk + ('a' - 'A')));
|
|
}
|
|
|
|
void JapaneseRomajiScheme::set_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases)
|
|
{
|
|
raw_input_ = raw_input_with_cases.empty() ? raw_input : raw_input_with_cases;
|
|
raw_input_.erase(std::remove_if(raw_input_.begin(), raw_input_.end(),
|
|
[](unsigned char ch) { return !std::isalpha(ch) && ch != '\'' && ch != '-'; }),
|
|
raw_input_.end());
|
|
key_strokes_.clear();
|
|
}
|
|
|
|
QueryRequest JapaneseRomajiScheme::build_request() const
|
|
{
|
|
QueryRequest request;
|
|
request.scheme = type();
|
|
request.raw_input_with_cases = raw_input_;
|
|
request.raw_input = raw_input_;
|
|
std::transform(request.raw_input.begin(), request.raw_input.end(), request.raw_input.begin(),
|
|
[](unsigned char ch) { return static_cast<char>(std::tolower(ch)); });
|
|
request.normalized_input = request.raw_input;
|
|
const auto converted = japanese::ConvertRomaji(request.raw_input);
|
|
request.raw_segmentation = request.raw_input_with_cases;
|
|
request.normalized_segmentation = converted.hiragana + converted.pending;
|
|
request.segmentation = request.normalized_segmentation;
|
|
request.key_strokes = key_strokes_;
|
|
request.valid = !request.raw_input.empty();
|
|
return request;
|
|
}
|
|
|
|
std::string JapaneseRomajiScheme::get_preedit() const
|
|
{
|
|
return raw_input_;
|
|
}
|
|
|
|
SchemeType JapaneseRomajiScheme::type() const
|
|
{
|
|
return SchemeType::JapaneseRomaji;
|
|
}
|