support left alignment for RTL text in edit mode

Vim mode does not support it for now.
This commit is contained in:
Le Tan 2019-04-26 19:43:56 +08:00
parent b3555cffba
commit 14617a4172

View File

@ -256,15 +256,43 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
int cursorWidth = m_cursorWidth;
int cursorPosition = p_context.cursorPosition - blpos;
if (drawCursor && m_cursorBlockMode != CursorBlock::None) {
if (cursorPosition > 0 && m_cursorBlockMode == CursorBlock::LeftSide) {
--cursorPosition;
auto direction = layout->textOption().textDirection();
bool needUpdateWidthViaSelection = true;
int deltaPosition = direction == Qt::RightToLeft ? -1 : 1;
// FIXME: the rect to update is error in RTL case.
if (m_cursorBlockMode == CursorBlock::LeftSide) {
if (direction == Qt::RightToLeft) {
if (cursorPosition == 0) {
cursorWidth = 1;
needUpdateWidthViaSelection = false;
}
} else {
if (cursorPosition > 0) {
--cursorPosition;
} else {
cursorWidth = 1;
needUpdateWidthViaSelection = false;
}
}
} else if (m_cursorBlockMode == CursorBlock::RightSide) {
if (direction == Qt::RightToLeft) {
if (cursorPosition < bllen - 1) {
++cursorPosition;
} else {
cursorWidth = 1;
needUpdateWidthViaSelection = false;
}
} else {
if (cursorPosition == bllen - 1) {
cursorWidth = m_virtualCursorBlockWidth;
} else {
needUpdateWidthViaSelection = false;
}
}
}
if (needUpdateWidthViaSelection) {
// Get the width of the selection to update cursor width.
cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, 1);
cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, deltaPosition);
if (cursorWidth < m_cursorWidth) {
cursorWidth = m_cursorWidth;
}
@ -274,6 +302,8 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
m_lastCursorBlockWidth = cursorWidth;
emit cursorBlockWidthUpdated(m_lastCursorBlockWidth);
}
Q_ASSERT(cursorWidth > 0);
}
// Draw cursor line block.
@ -511,6 +541,26 @@ void VTextDocumentLayout::clearBlockLayout(QTextBlock &p_block)
info->reset();
}
// From Qt's qguiapplication_p.h.
static Qt::Alignment visualAlignment(Qt::LayoutDirection p_direction,
Qt::Alignment p_alignment)
{
if (!(p_alignment & Qt::AlignHorizontal_Mask)) {
p_alignment |= Qt::AlignLeft;
}
if (!(p_alignment & Qt::AlignAbsolute)
&& (p_alignment & (Qt::AlignLeft | Qt::AlignRight))) {
if (p_direction == Qt::RightToLeft) {
p_alignment ^= (Qt::AlignLeft | Qt::AlignRight);
}
p_alignment |= Qt::AlignAbsolute;
}
return p_alignment;
}
void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block)
{
QTextDocument *doc = document();
@ -518,6 +568,21 @@ void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block)
QTextLayout *tl = p_block.layout();
QTextOption option = doc->defaultTextOption();
{
auto direction = p_block.textDirection();
option.setTextDirection(direction);
auto alignment = option.alignment();
QTextBlockFormat blockFormat = p_block.blockFormat();
if (blockFormat.hasProperty(QTextFormat::BlockAlignment)) {
alignment = blockFormat.alignment();
}
// For paragraph that are RTL, alignment is auto-reversed.
option.setAlignment(visualAlignment(direction, alignment));
}
tl->setTextOption(option);
int extraMargin = 0;
@ -1125,7 +1190,8 @@ int VTextDocumentLayout::getTextWidthWithinTextLine(const QTextLayout *p_layout,
QTextLine line = p_layout->lineForTextPosition(p_pos);
V_ASSERT(line.isValid());
V_ASSERT(p_pos + p_length <= line.textStart() + line.textLength());
return line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos);
V_ASSERT(p_pos + p_length >= 0);
return qAbs(line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos));
}
void VTextDocumentLayout::updateBlockByNumber(int p_blockNumber)