summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
authorKhaled Hosny <khaled@libreoffice.org>2023-08-16 15:17:41 +0300
committerخالد حسني <khaled@libreoffice.org>2023-09-04 18:17:15 +0200
commitfb43c497f2cc71c988a967fa0126c27561f8c16d (patch)
treea02a71b116a9dcfcec1fb5a0ed9095b3af135e9d /starmath
parent5c5c71266ff14493975f20ff5807f31565a3f909 (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.hxx7
-rw-r--r--starmath/source/ElementsDockingWindow.cxx2
-rw-r--r--starmath/source/document.cxx41
-rw-r--r--starmath/source/visitors.cxx15
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 ) );