summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-05-03 21:17:56 +0100
committerCaolán McNamara <caolanm@redhat.com>2022-05-04 11:56:51 +0200
commitcceeb407c61e9af14a300e8fcfaa57fd91ede49e (patch)
tree24c6019204a6c73f1883c94fd1e28ef2b3ea987c
parent609402c6167c33f74b17e0c6c4ba093b343abd01 (diff)
Related: tdf#131725 match the basegfx translation to the mirror logic
that is used in the traditional code path, this will fix vcl RTL scrollbars in otherwise LTR UI Change-Id: I1451f7e17b93b0339ded6d33147df6415274ebfc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133780 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--vcl/inc/salgdi.hxx14
-rw-r--r--vcl/source/gdi/salgdilayout.cxx103
2 files changed, 82 insertions, 35 deletions
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index eed8ab7160ac..75938afecece 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -638,10 +638,18 @@ private:
SalLayoutFlags m_nLayout; //< 0: mirroring off, 1: mirror x-axis
// for buffering the Mirror-Matrix, see ::getMirror
+ enum class MirrorMode
+ {
+ NONE,
+ Antiparallel,
+ AntiparallelBiDi,
+ BiDi
+ };
+ MirrorMode m_eLastMirrorMode;
+ tools::Long m_nLastMirrorTranslation;
basegfx::B2DHomMatrix m_aLastMirror;
- tools::Long m_aLastMirrorW;
- tools::Long m_nLastMirrorDeviceLTRButBiDiRtlTranslate;
- bool m_bLastMirrorDeviceLTRButBiDiRtlSet;
+
+ MirrorMode GetMirrorMode(const OutputDevice& rOutDev) const;
protected:
/// flags which hold the SetAntialiasing() value from OutputDevice
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 89f9d0321daf..a998a7483df8 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -53,9 +53,8 @@ SalFrameGeometry SalFrame::GetGeometry() const
SalGraphics::SalGraphics()
: m_nLayout( SalLayoutFlags::NONE ),
- m_aLastMirrorW(0),
- m_nLastMirrorDeviceLTRButBiDiRtlTranslate(0),
- m_bLastMirrorDeviceLTRButBiDiRtlSet(false),
+ m_eLastMirrorMode(MirrorMode::NONE),
+ m_nLastMirrorTranslation(0),
m_bAntiAlias(false),
m_bTextRenderModeForResolutionIndependentLayout(false)
{
@@ -271,50 +270,90 @@ basegfx::B2DPolyPolygon SalGraphics::mirror( const basegfx::B2DPolyPolygon& i_rP
}
}
+SalGraphics::MirrorMode SalGraphics::GetMirrorMode(const OutputDevice& rOutDev) const
+{
+ if (rOutDev.ImplIsAntiparallel())
+ {
+ if (m_nLayout & SalLayoutFlags::BiDiRtl)
+ return MirrorMode::AntiparallelBiDi;
+ else
+ return MirrorMode::Antiparallel;
+ }
+ else if (m_nLayout & SalLayoutFlags::BiDiRtl)
+ return MirrorMode::BiDi;
+ return MirrorMode::NONE;
+}
+
const basegfx::B2DHomMatrix& SalGraphics::getMirror( const OutputDevice& i_rOutDev ) const
{
// get mirroring transformation
- const tools::Long w = GetDeviceWidth(i_rOutDev);
- SAL_WARN_IF( !w, "vcl", "missing graphics width" );
-
- const bool bMirrorDeviceLTRButBiDiRtlSet = !i_rOutDev.IsRTLEnabled();
- tools::Long nMirrorDeviceLTRButBiDiRtlTranslate(0);
- if (bMirrorDeviceLTRButBiDiRtlSet)
- nMirrorDeviceLTRButBiDiRtlTranslate = w - i_rOutDev.GetOutputWidthPixel() - (2 * i_rOutDev.GetOutOffXPixel());
+ MirrorMode eNewMirrorMode = GetMirrorMode(i_rOutDev);
+ tools::Long nTranslate(0);
- // if the device width, or mirror state of the device changed, then m_aLastMirror is invalid
- bool bLastMirrorValid = w == m_aLastMirrorW && bMirrorDeviceLTRButBiDiRtlSet == m_bLastMirrorDeviceLTRButBiDiRtlSet;
- if (bLastMirrorValid && bMirrorDeviceLTRButBiDiRtlSet)
+ switch (eNewMirrorMode)
{
- // if the device is in the unusual mode of a LTR device, but layout flags of SalLayoutFlags::BiDiRtl are
- // in use, then the m_aLastMirror is invalid if the distance it should translate has changed
- bLastMirrorValid = nMirrorDeviceLTRButBiDiRtlTranslate == m_nLastMirrorDeviceLTRButBiDiRtlTranslate;
+ case MirrorMode::AntiparallelBiDi:
+ {
+ const tools::Long w = GetDeviceWidth(i_rOutDev);
+ SAL_WARN_IF(!w, "vcl", "missing graphics width");
+ nTranslate = w - i_rOutDev.GetOutputWidthPixel() - (2 * i_rOutDev.GetOutOffXPixel());
+ break;
+ }
+ case MirrorMode::Antiparallel:
+ {
+ nTranslate = i_rOutDev.GetOutputWidthPixel() + (2 * i_rOutDev.GetOutOffXPixel()) - 1;
+ break;
+ }
+ case MirrorMode::BiDi:
+ {
+ const tools::Long w = GetDeviceWidth(i_rOutDev);
+ SAL_WARN_IF(!w, "vcl", "missing graphics width");
+ nTranslate = w - 1;
+ break;
+ }
+ case MirrorMode::NONE:
+ break;
}
+ // if the translation (due to device width), or mirror state of the device changed, then m_aLastMirror is invalid
+ bool bLastMirrorValid = eNewMirrorMode == m_eLastMirrorMode && nTranslate == m_nLastMirrorTranslation;
if (!bLastMirrorValid)
{
- const_cast<SalGraphics*>(this)->m_aLastMirrorW = w;
- const_cast<SalGraphics*>(this)->m_bLastMirrorDeviceLTRButBiDiRtlSet = bMirrorDeviceLTRButBiDiRtlSet;
- const_cast<SalGraphics*>(this)->m_nLastMirrorDeviceLTRButBiDiRtlTranslate = nMirrorDeviceLTRButBiDiRtlTranslate;
+ const_cast<SalGraphics*>(this)->m_nLastMirrorTranslation = nTranslate;
+ const_cast<SalGraphics*>(this)->m_eLastMirrorMode = eNewMirrorMode;
- if(w)
+ switch (eNewMirrorMode)
{
- if (bMirrorDeviceLTRButBiDiRtlSet)
+ // mirror this window back
+ case MirrorMode::AntiparallelBiDi:
{
/* This path gets exercised in calc's RTL UI (e.g. SAL_RTL_ENABLED=1)
with its LTR horizontal scrollbar */
// Original code was:
- // // mirror this window back
// double devX = w-i_rOutDev.GetOutputWidthPixel()-i_rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
// aRet.setX( devX + (i_rPoint.getX() - i_rOutDev.GetOutOffXPixel()) );
- // I do not really understand the comment 'mirror this window back', so cannot guarantee
- // that this works as before, but I have reduced this (by re-placing and re-formatting) to
- // a simple translation:
const_cast<SalGraphics*>(this)->m_aLastMirror = basegfx::utils::createTranslateB2DHomMatrix(
- nMirrorDeviceLTRButBiDiRtlTranslate, 0.0);
+ nTranslate, 0.0);
+ break;
}
- else
+ case MirrorMode::Antiparallel:
+ {
+ /* This path gets exercised in writers's LTR UI with a RTL horizontal
+ scrollbar, cross-reference dialog populated from contents from a
+ RTL document tdf#131725 */
+
+ // Original code was;
+ // tools::Long devX = rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
+ // x = rOutDev.GetOutputWidthPixel() - (x - devX) + rOutDev.GetOutOffXPixel() - 1;
+ const_cast<SalGraphics*>(this)->m_aLastMirror = basegfx::utils::createScaleTranslateB2DHomMatrix(
+ -1.0,
+ 1.0,
+ nTranslate,
+ 0.0);
+ break;
+ }
+ case MirrorMode::BiDi:
{
// Original code was:
// aRet.setX( w-1-i_rPoint.getX() );
@@ -324,13 +363,13 @@ const basegfx::B2DHomMatrix& SalGraphics::getMirror( const OutputDevice& i_rOutD
const_cast<SalGraphics*>(this)->m_aLastMirror = basegfx::utils::createScaleTranslateB2DHomMatrix(
-1.0,
1.0,
- w-1,
+ nTranslate,
0.0);
+ break;
}
- }
- else
- {
- const_cast<SalGraphics*>(this)->m_aLastMirror.identity();
+ case MirrorMode::NONE:
+ const_cast<SalGraphics*>(this)->m_aLastMirror.identity();
+ break;
}
}