diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_article.cpp b/Telegram/SourceFiles/iv/markdown/iv_markdown_article.cpp index 34f1e25791..3363f86b03 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_article.cpp +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_article.cpp @@ -3576,6 +3576,7 @@ private: void invalidateGeometry(); [[nodiscard]] const style::Markdown &layoutStyle() const; + [[nodiscard]] bool contentRtl() const; [[nodiscard]] MarkdownArticleScrollOwnerIdentity scrollOwnerIdentity( const LaidOutBlock &block, const std::vector &preparedPath) const; @@ -3887,6 +3888,7 @@ void MarkdownArticle::Impl::updatePreparedLeaf( } auto context = LayoutContext(); + context.rtl = contentRtl(); context.syntaxHighlightTracker = this; context.repaint = _textRepaint; context.repaintRect = _textRepaintRect; @@ -5233,6 +5235,10 @@ const style::Markdown &MarkdownArticle::Impl::layoutStyle() const { return _style; } +bool MarkdownArticle::Impl::contentRtl() const { + return _content.richPage && _content.richPage->rtl; +} + MarkdownArticleScrollOwnerIdentity MarkdownArticle::Impl::scrollOwnerIdentity( const LaidOutBlock &block, const std::vector &preparedPath) const { @@ -5738,7 +5744,7 @@ void MarkdownArticle::Impl::finalizeRelayout(int heightBottom) { _laidOutWidth = std::min( _width, std::max( - ArticleContentMaxRight(_blocks, layoutStyle()) + page.right(), + ArticleContentMaxRight(_blocks, layoutStyle(), contentRtl()) + page.right(), page.left() + page.right() + 1)); pruneTaskMarkerRuntimes(); prunePlaceholderRuntimes(); @@ -5786,6 +5792,7 @@ void MarkdownArticle::Impl::relayout(int width) { .mediaPixelScale = _mediaPixelScale, .useArticleBands = true, .editMode = _content.editMode, + .rtl = contentRtl(), .syntaxHighlightTracker = this, .cachedTextLeafs = &_cachedTextLeafs, .repaint = _textRepaint, @@ -5874,6 +5881,7 @@ void MarkdownArticle::Impl::relayoutRetained(int width) { .mediaPixelScale = _mediaPixelScale, .useArticleBands = true, .editMode = _content.editMode, + .rtl = contentRtl(), .syntaxHighlightTracker = this, .cachedTextLeafs = &_cachedTextLeafs, .repaint = _textRepaint, diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_blocks.h b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_blocks.h index fc2a263b33..7abdf225ba 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_blocks.h +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_blocks.h @@ -317,6 +317,7 @@ struct LayoutContext { bool tightList = false; bool useArticleBands = false; bool editMode = false; + bool rtl = false; bool hideEmptyQuoteAuthor = false; bool allowAsyncSyntaxHighlighting = true; CodeBlockSyntaxHighlightTracker *syntaxHighlightTracker = nullptr; diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.cpp b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.cpp index 8dc5ae3ca6..f9a78e28af 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.cpp +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.cpp @@ -2823,7 +2823,9 @@ int LayoutBlocks( currentScrollOwner, logicalWidth); block->markerWidth = std::max(list.markerWidth, markerTextWidth); - const auto bodyLeft = left + block->markerWidth + list.markerSkip; + const auto bodyLeft = context.rtl + ? left + : (left + block->markerWidth + list.markerSkip); const auto bodyWidth = std::max( width - block->markerWidth - list.markerSkip, 1); @@ -2872,13 +2874,18 @@ int LayoutBlocks( (bodyLineHeight - markerTextHeight) / 2, 0); if (task) { + const auto markerLeft = context.rtl + ? (left + width - list.taskCheck.diameter) + : left; block->markerRect = QRect( - left, + markerLeft, markerTop, list.taskCheck.diameter, list.taskCheck.diameter); } else if (ordered) { - const auto markerLeft = left + block->markerWidth - markerTextWidth; + const auto markerLeft = context.rtl + ? (left + width - block->markerWidth) + : (left + block->markerWidth - markerTextWidth); const auto markerLeafBaseline = LeafFirstLineBaseline( block->marker, QRect(0, 0, markerTextWidth, markerTextHeight), @@ -2889,7 +2896,10 @@ int LayoutBlocks( markerTextWidth, markerTextHeight); } else { - block->markerCenter = BulletMarkerCenter(left, markerBaseline, st); + const auto center = BulletMarkerCenter(left, markerBaseline, st); + block->markerCenter = context.rtl + ? QPoint(left + width - (center.x() - left), center.y()) + : center; } block->contentRect = QRect(bodyLeft, top, bodyWidth, rowHeight); block->horizontalScrollMax = scrollOwner @@ -2943,7 +2953,7 @@ int LayoutBlocks( const auto markerColumn = context.listItemContentShift; const auto step = std::max(st.textPadding.left(), markerColumn); const auto indent = depthDelta * step - markerColumn; - const auto listLeft = left + indent; + const auto listLeft = context.rtl ? left : (left + indent); const auto listWidth = std::max(width - indent, 1); const auto currentScrollOwner = NextActiveScrollOwner( analysis, @@ -3746,7 +3756,8 @@ int LayoutBlocks( [[nodiscard]] int BlockContentMaxRight( const LaidOutBlock &block, - const style::Markdown &st) { + const style::Markdown &st, + bool rtl) { const auto outerRight = block.outer.x() + block.outer.width(); const auto textRight = [&] { const auto &leaf = block.placeholderLeaf.isEmpty() @@ -3760,7 +3771,7 @@ int LayoutBlocks( const auto childrenRight = [&] { auto result = 0; for (const auto &child : block.children) { - result = std::max(result, BlockContentMaxRight(child, st)); + result = std::max(result, BlockContentMaxRight(child, st, rtl)); } return result; }; @@ -3821,11 +3832,13 @@ int LayoutBlocks( case PreparedBlockKind::List: return std::min(childrenRight(), outerRight); case PreparedBlockKind::ListItem: - return std::min( - std::max( - block.outer.x() + block.markerWidth, - childrenRight()), - outerRight); + return rtl + ? outerRight + : std::min( + std::max( + block.outer.x() + block.markerWidth, + childrenRight()), + outerRight); case PreparedBlockKind::Quote: return block.pullquote ? outerRight @@ -4026,7 +4039,8 @@ std::optional RecountLaidOutBlocks( int ArticleContentMaxRight( const std::vector &blocks, - const style::Markdown &st) { + const style::Markdown &st, + bool rtl) { auto result = 0; for (const auto &block : blocks) { const auto bandPadding = UsesMediaBand(block.kind) @@ -4034,7 +4048,7 @@ int ArticleContentMaxRight( : st.textPadding; result = std::max( result, - BlockContentMaxRight(block, st) - bandPadding.left()); + BlockContentMaxRight(block, st, rtl) - bandPadding.left()); } return result; } diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.h b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.h index e8d0910fe0..4d5eae9a3e 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.h +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_article_layout_structure.h @@ -35,6 +35,7 @@ namespace Iv::Markdown { LayoutContext context); [[nodiscard]] int ArticleContentMaxRight( const std::vector &blocks, - const style::Markdown &st); + const style::Markdown &st, + bool rtl); } // namespace Iv::Markdown