diff options
author | Khaled Hosny <khaled@libreoffice.org> | 2023-08-16 15:17:41 +0300 |
---|---|---|
committer | خالد حسني <khaled@libreoffice.org> | 2023-09-04 18:17:15 +0200 |
commit | fb43c497f2cc71c988a967fa0126c27561f8c16d (patch) | |
tree | a02a71b116a9dcfcec1fb5a0ed9095b3af135e9d /starmath | |
parent | 5c5c71266ff14493975f20ff5807f31565a3f909 (diff) |
tdf#134193: Support rendering math in RTL mode
Respect IsRightToLeft property and render accordingly.
This also fixes math rendering in RTL UI, which was incorrectly rendered RTL.
Change-Id: Id8520930f09a21daa1c70e40a765ac25572ea994
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155738
Tested-by: Jenkins
Reviewed-by: خالد حسني <khaled@libreoffice.org>
Diffstat (limited to 'starmath')
-rw-r--r-- | starmath/inc/visitors.hxx | 7 | ||||
-rw-r--r-- | starmath/source/ElementsDockingWindow.cxx | 2 | ||||
-rw-r--r-- | starmath/source/document.cxx | 41 | ||||
-rw-r--r-- | starmath/source/visitors.cxx | 15 |
4 files changed, 53 insertions, 12 deletions
diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx index eaf329034c7d..c1a2a8983286 100644 --- a/starmath/inc/visitors.hxx +++ b/starmath/inc/visitors.hxx @@ -211,12 +211,16 @@ public: * @param rDevice Device to draw on * @param position Offset on device to draw the formula * @param pTree Formula tree to draw + * @param rFormat Formula formatting settings * @remarks This constructor will do the drawing, no need to anything more. */ - SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree ) + SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree, const SmFormat& rFormat ) : mrDev( rDevice ) , maPosition( position ) + , mrFormat( rFormat ) { + if (mrFormat.IsRightToLeft()) + mrDev.ReMirror(maPosition); pTree->Accept( this ); } virtual ~SmDrawingVisitor() {} @@ -265,6 +269,7 @@ private: so if needed cache it locally on the stack. */ Point maPosition; + const SmFormat& mrFormat; }; // SmSetSelectionVisitor diff --git a/starmath/source/ElementsDockingWindow.cxx b/starmath/source/ElementsDockingWindow.cxx index 7fdfb3b3ec49..d1feabd921a9 100644 --- a/starmath/source/ElementsDockingWindow.cxx +++ b/starmath/source/ElementsDockingWindow.cxx @@ -546,7 +546,7 @@ void SmElementsControl::addElement(const OUString& aElementVisual, const OUStrin Size aSize = pDevice->LogicToPixel(Size(pNode->GetWidth(), pNode->GetHeight())); aSize.extendBy(10, 0); // Add 5 pixels from both sides to accommodate extending parts of italics pDevice->SetOutputSizePixel(aSize); - SmDrawingVisitor(*pDevice, pDevice->PixelToLogic(Point(5, 0)), pNode.get()); + SmDrawingVisitor(*pDevice, pDevice->PixelToLogic(Point(5, 0)), pNode.get(), maFormat); maItemDatas.push_back(std::make_unique<ElementData>(aElementSource, aHelpText)); const OUString aId(weld::toId(maItemDatas.back().get())); diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx index c0f28ac18190..9bdaad7530e6 100644 --- a/starmath/source/document.cxx +++ b/starmath/source/document.cxx @@ -261,10 +261,18 @@ void SmDocShell::ArrangeFormula() const SmFormat &rFormat = GetFormat(); mpTree->Prepare(rFormat, *this, 0); - // format/draw formulas always from left to right, - // and numbers should not be converted - pOutDev->Push(vcl::PushFlags::TEXTLAYOUTMODE | vcl::PushFlags::TEXTLANGUAGE); - pOutDev->SetLayoutMode( vcl::text::ComplexTextLayoutFlags::Default ); + pOutDev->Push(vcl::PushFlags::TEXTLAYOUTMODE | vcl::PushFlags::TEXTLANGUAGE | + vcl::PushFlags::RTLENABLED); + + // We want the device to always be LTR, we handle RTL formulas ourselves. + pOutDev->EnableRTL(false); + + // For RTL formulas, we want the brackets to be mirrored. + bool bRTL = GetFormat().IsRightToLeft(); + pOutDev->SetLayoutMode(bRTL ? vcl::text::ComplexTextLayoutFlags::BiDiRtl + : vcl::text::ComplexTextLayoutFlags::Default); + + // Numbers should not be converted, for now. pOutDev->SetDigitLanguage( LANGUAGE_ENGLISH ); mpTree->Arrange(*pOutDev, rFormat); @@ -313,6 +321,8 @@ void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSel ArrangeFormula(); + bool bRTL = GetFormat().IsRightToLeft(); + // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference // device and aren't aligned to that either. So now there can be a difference between the // VisArea (i.e. the size within the client) and the current size. @@ -321,6 +331,10 @@ void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSel rPosition.AdjustX(maFormat.GetDistance( DIS_LEFTSPACE ) ); rPosition.AdjustY(maFormat.GetDistance( DIS_TOPSPACE ) ); + Point aPosition(rPosition); + if (bRTL) + aPosition.AdjustX(GetSize().Width() - maFormat.GetDistance(DIS_LEFTSPACE) - maFormat.GetDistance(DIS_RIGHTSPACE)); + //! in case of high contrast-mode (accessibility option!) //! the draw mode needs to be set to default, because when embedding //! Math for example in Calc in "a over b" the fraction bar may not @@ -335,20 +349,27 @@ void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSel bRestoreDrawMode = true; } - // format/draw formulas always from left to right - // and numbers should not be converted - rDev.Push(vcl::PushFlags::TEXTLAYOUTMODE | vcl::PushFlags::TEXTLANGUAGE); - rDev.SetLayoutMode( vcl::text::ComplexTextLayoutFlags::Default ); + rDev.Push(vcl::PushFlags::TEXTLAYOUTMODE | vcl::PushFlags::TEXTLANGUAGE | + vcl::PushFlags::RTLENABLED); + + // We want the device to always be LTR, we handle RTL formulas ourselves. + rDev.EnableRTL(false); + + // For RTL formulas, we want the brackets to be mirrored. + rDev.SetLayoutMode(bRTL ? vcl::text::ComplexTextLayoutFlags::BiDiRtl + : vcl::text::ComplexTextLayoutFlags::Default); + + // Numbers should not be converted, for now. rDev.SetDigitLanguage( LANGUAGE_ENGLISH ); //Set selection if any if(mpCursor && bDrawSelection){ mpCursor->AnnotateSelection(); - SmSelectionDrawingVisitor(rDev, mpTree.get(), rPosition); + SmSelectionDrawingVisitor(rDev, mpTree.get(), aPosition); } //Drawing using visitor - SmDrawingVisitor(rDev, rPosition, mpTree.get()); + SmDrawingVisitor(rDev, aPosition, mpTree.get(), GetFormat()); rDev.Pop(); diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx index a15a62a4b048..cece754de276 100644 --- a/starmath/source/visitors.cxx +++ b/starmath/source/visitors.cxx @@ -437,6 +437,10 @@ void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode ) Point aBarPos( maPosition + aBarOffset ); tools::Rectangle aBar( aBarPos, Size( nBarWidth, nBarHeight ) ); + + if (mrFormat.IsRightToLeft()) + mrDev.ReMirror(aBar); + //! avoid GROWING AND SHRINKING of drawn rectangle when constantly //! increasing zoomfactor. // This is done by shifting its output-position to a point that @@ -460,6 +464,10 @@ void SmDrawingVisitor::Visit( SmPolyLineNode* pNode ) Point aOffset ( Point( ) - pNode->GetPolygon( ).GetBoundRect( ).TopLeft( ) + Point( nBorderwidth, nBorderwidth ) ), aPos ( maPosition + aOffset ); + + if (mrFormat.IsRightToLeft()) + mrDev.ReMirror(aPos); + pNode->GetPolygon( ).Move( aPos.X( ), aPos.Y( ) ); //Works because Polygon wraps a pointer SmTmpDevice aTmpDev ( mrDev, false ); @@ -489,6 +497,9 @@ void SmDrawingVisitor::Visit( SmRectangleNode* pNode ) SAL_WARN_IF( aTmp.IsEmpty(), "starmath", "Empty rectangle" ); + if (mrFormat.IsRightToLeft()) + mrDev.ReMirror(aTmp); + //! avoid GROWING AND SHRINKING of drawn rectangle when constantly //! increasing zoomfactor. // This is done by shifting its output-position to a point that @@ -509,6 +520,10 @@ void SmDrawingVisitor::DrawTextNode( SmTextNode* pNode ) Point aPos ( maPosition ); aPos.AdjustY(pNode->GetBaselineOffset( ) ); + + if (mrFormat.IsRightToLeft()) + mrDev.ReMirror(aPos); + // round to pixel coordinate aPos = mrDev.PixelToLogic( mrDev.LogicToPixel( aPos ) ); |