|  | @@ -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;
 | 
	
		
			
				|  |  | +                        needUpdateWidthViaSelection = false;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if (cursorPosition == bllen - 1) {
 | 
	
		
			
				|  |  | -                cursorWidth = m_virtualCursorBlockWidth;
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | +            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)
 |