Skip to content

Commit

Permalink
Emulate IMM32 vertical writing protocol in TSF
Browse files Browse the repository at this point in the history
  • Loading branch information
yukawa committed Oct 14, 2023
1 parent 326bf0e commit 9f945f9
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 11 deletions.
4 changes: 4 additions & 0 deletions src/protocol/renderer_command.proto
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ message RendererCommand {
optional Point top_left = 2;
optional uint32 line_height = 3;
optional Rectangle document_area = 4;
// A quick solution for vertical writing support.
// Strictly speaking, this is not part of IMECHARPOSITION in IMM32 and
// is better to be generarized for other platforms.
optional bool vertical_writing = 5;
}

// Visual information about mode indicator.
Expand Down
9 changes: 5 additions & 4 deletions src/renderer/win32/win32_renderer_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -763,10 +763,11 @@ double LayoutManager::GetScalingFactor(HWND window_handle) const {

LayoutManager::WritingDirection LayoutManager::GetWritingDirection(
const commands::RendererCommand_ApplicationInfo &app_info) {
// TODO(https://github.com/google/mozc/issues/362): Implement this for TSF.
// When fixing this, we also need to update Chromium.
// https://chromium-review.googlesource.com/c/chromium/src/+/4023235
return WRITING_DIRECTION_UNSPECIFIED;
if (!app_info.composition_target().has_vertical_writing()) {
return WRITING_DIRECTION_UNSPECIFIED;
}
return app_info.composition_target().vertical_writing()
? VERTICAL_WRITING : HORIZONTAL_WRITING;
}

bool LayoutManager::LayoutCandidateWindow(
Expand Down
27 changes: 27 additions & 0 deletions src/win32/tip/tip_range_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ constexpr GUID kGuidPropInputscope = {
0x4a5b,
{0x9a, 0xf6, 0x59, 0x2a, 0x59, 0x5c, 0x77, 0x8d}};

// TSATTRID_Text_VerticalWriting
constexpr GUID kGuidAttrIdTextVerticalWriting = {
0x6bba8195,
0x046f,
0x4ea9,
{0xb3, 0x11, 0x97, 0xfd, 0x66, 0xc4, 0x27, 0x4b}};

HRESULT GetReadOnlyAppProperty(ITfRange *range, TfEditCookie read_cookie,
const GUID &guid, VARIANT *variant_addr) {
HRESULT result = S_OK;
Expand Down Expand Up @@ -214,6 +221,26 @@ HRESULT TipRangeUtil::GetInputScopes(ITfRange *range, TfEditCookie read_cookie,
return S_OK;
}

HRESULT TipRangeUtil::IsVerticalWriting(ITfRange *range, TfEditCookie read_cookie,
bool *vertical_writing) {
if (vertical_writing == nullptr) {
return E_FAIL;
}
*vertical_writing = false;

wil::unique_variant variant;
HRESULT result = GetReadOnlyAppProperty(range,
read_cookie,
kGuidAttrIdTextVerticalWriting,
variant.reset_and_addressof());
if (FAILED(result)) {
return result;
}
*vertical_writing = (variant.vt == VT_BOOL && variant.boolVal != 0);
return S_OK;
}


bool TipRangeUtil::IsRangeCovered(TfEditCookie edit_cookie,
ITfRange *range_test, ITfRange *range_cover) {
HRESULT result = S_OK;
Expand Down
5 changes: 5 additions & 0 deletions src/win32/tip/tip_range_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class TipRangeUtil {
static HRESULT GetInputScopes(ITfRange *range, TfEditCookie read_cookie,
std::vector<InputScope> *input_scopes);

// Retrieves whether the specified |range| is for vertical writing or not.
// Returns the general result code.
static HRESULT IsVerticalWriting(ITfRange *range, TfEditCookie read_cookie,
bool *vertical_writing);

// Checks whether or not |range_test| becomes a subset of |range_cover|.
static bool IsRangeCovered(TfEditCookie edit_cookie, ITfRange *range_test,
ITfRange *range_cover);
Expand Down
43 changes: 36 additions & 7 deletions src/win32/tip/tip_ui_handler_conventional.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,42 @@ bool FillCharPosition(TipPrivateContext *private_context, ITfContext *context,
return false;
}

RendererCommand::Point *top_left =
app_info->mutable_composition_target()->mutable_top_left();
top_left->set_x(text_rect.left);
top_left->set_y(text_rect.top);
app_info->mutable_composition_target()->set_position(0);
app_info->mutable_composition_target()->set_line_height(text_rect.bottom -
text_rect.top);
auto *composition_target = app_info->mutable_composition_target();
composition_target->set_position(0);

bool vertical_writing = false;
if (SUCCEEDED(TipRangeUtil::IsVerticalWriting(
target_range.get(), read_cookie, &vertical_writing))) {
composition_target->set_vertical_writing(vertical_writing);
}

RendererCommand::Point *point = composition_target->mutable_top_left();
if (vertical_writing) {
// [Vertical Writing]
// |
// +-----< (pt)
// | |
// |-----+
// | (cLineHeight)
// |
// |
// v
// (Base Line)
point->set_x(text_rect.right);
point->set_y(text_rect.top);
composition_target->set_line_height(text_rect.right - text_rect.left);
} else {
// [Horizontal Writing]
// (pt)
// v_____
// | |
// | | (cLineHeight)
// | |
// --+-----+----------> (Base Line)
point->set_x(text_rect.left);
point->set_y(text_rect.top);
composition_target->set_line_height(text_rect.bottom - text_rect.top);
}

RendererCommand::Rectangle *area =
app_info->mutable_composition_target()->mutable_document_area();
Expand Down

0 comments on commit 9f945f9

Please sign in to comment.