summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-01-18 15:35:47 +0000
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-01-19 15:41:24 +0000
commit4fd0f5715efb435160814e8c5f514b9ad1752c49 (patch)
tree652c4a5e2ae5715752a0a5a1017fe3140f80e01e
parent42849da8f266972ef370104c332d74ff7b15fc71 (diff)
Resolves: tdf#98593 buttons in writer show different text at different zooms
The DrawControlText always renders with a reference device positions but we pass in a rectangle which is derived a different way. So, add a GetControlTextRect which operates on the same reference device as DrawControlText so the rectangles match The rectangle is mapped from pixels to logic and back from logic to pixel, so add an argument to store the logic size from GetControlTextRect and re-use it without conversion on the cases where we pass back the original rectangle zooming in/out on the button in writer is now stable wrt text shown at all zoom levels Reviewed-on: https://gerrit.libreoffice.org/33277 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit db9ef688edd86b31606e0dd6df6a77732faca49b) change DrawControlText to return new rect rather than change old one (cherry picked from commit bc6479e92b56df742dd7339d337ffc78d2f9e4a1) Ref...DeviceTextLayout::GetTextArray is only called by Ref...DeviceTextLayout so set it as private to de-confuse this a little (cherry picked from commit 3d002fdb8738d9bbc9b04c0270510e349bd58149) d5c80ff263e429d4239a844db216e87a656edb2e dde7f78a767227cc2d52e417b6c39d12e1339745 Change-Id: Ic581eca67d0ff265e2753ab8b6c40e8fca7e6ae4 Reviewed-on: https://gerrit.libreoffice.org/33282 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r--include/vcl/ctrl.hxx16
-rw-r--r--vcl/inc/textlayout.hxx7
-rw-r--r--vcl/source/control/button.cxx11
-rw-r--r--vcl/source/control/ctrl.cxx42
-rw-r--r--vcl/source/control/fixed.cxx4
-rw-r--r--vcl/source/control/tabctrl.cxx4
-rw-r--r--vcl/source/gdi/textlayout.cxx56
7 files changed, 112 insertions, 28 deletions
diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx
index dede22f9d680..605f52cf4b19 100644
--- a/include/vcl/ctrl.hxx
+++ b/include/vcl/ctrl.hxx
@@ -80,12 +80,18 @@ protected:
If no reference device is set, the draw request will simply be forwarded to OutputDevice::DrawText. Otherwise,
the text will be rendered according to the metrics at the reference device.
- Note that the given rectangle might be modified, it will contain the result of a GetTextRect call (either
- directly at the target device, or taking the reference device into account) when returning.
+ return will contain the result of a GetTextRect call (either directly
+ at the target device, or taking the reference device into account) when
+ returning.
*/
- void DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect,
- const OUString& _rStr, DrawTextFlags _nStyle,
- MetricVector* _pVector, OUString* _pDisplayText ) const;
+ Rectangle DrawControlText( OutputDevice& _rTargetDevice, const Rectangle& _rRect,
+ const OUString& _rStr, DrawTextFlags _nStyle,
+ MetricVector* _pVector, OUString* _pDisplayText,
+ const Size* i_pDeviceSize = nullptr ) const;
+
+ Rectangle GetControlTextRect( OutputDevice& _rTargetDevice, const Rectangle & rRect,
+ const OUString& _rStr, DrawTextFlags _nStyle,
+ Size* o_pDeviceSize = nullptr ) const;
virtual const vcl::Font&
GetCanonicalFont( const StyleSettings& _rStyle ) const;
diff --git a/vcl/inc/textlayout.hxx b/vcl/inc/textlayout.hxx
index f057c5c3dd1d..b858a67fdbe6 100644
--- a/vcl/inc/textlayout.hxx
+++ b/vcl/inc/textlayout.hxx
@@ -91,8 +91,11 @@ namespace vcl
virtual ~ControlTextRenderer();
Rectangle DrawText( const Rectangle& _rRect,
- const OUString& _rText, DrawTextFlags _nStyle = DrawTextFlags::NONE,
- MetricVector* _pVector = nullptr, OUString* _pDisplayText = nullptr );
+ const OUString& _rText, DrawTextFlags _nStyle,
+ MetricVector* _pVector, OUString* _pDisplayText, const Size* i_pDeviceSize );
+
+ Rectangle GetTextRect( const Rectangle& _rRect,
+ const OUString& _rText, DrawTextFlags _nStyle, Size* o_pDeviceSize );
private:
ControlTextRenderer( const ControlTextRenderer& ) = delete;
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 570354afd892..8c95f2de8ea9 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -285,7 +285,7 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
}
else if (bDrawText && !bDrawImage && !bHasSymbol)
{
- DrawControlText(*pDev, aOutRect, aText, nTextStyle, nullptr, nullptr);
+ aOutRect = DrawControlText(*pDev, aOutRect, aText, nTextStyle, nullptr, nullptr);
ImplSetFocusRect(aOutRect);
rSize = aOutRect.GetSize();
@@ -299,6 +299,7 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
Size aTextSize;
Size aSymbolSize;
+ Size aDeviceTextSize;
Size aMax;
Point aImagePos = rPos;
Point aTextPos = rPos;
@@ -358,7 +359,7 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
aRect.Bottom() -= (aImageSize.Height() + nImageSep);
}
- aRect = pDev->GetTextRect(aRect, aText, nTextStyle);
+ aRect = GetControlTextRect(*pDev, aRect, aText, nTextStyle, &aDeviceTextSize);
aTextSize = aRect.GetSize();
aTSSize.Width() += aTextSize.Width();
@@ -510,9 +511,9 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
if (bDrawText)
{
- Rectangle aTOutRect( aTextPos, aTextSize );
- ImplSetFocusRect( aTOutRect );
- DrawControlText( *pDev, aTOutRect, aText, nTextStyle, nullptr, nullptr );
+ const Rectangle aTOutRect(aTextPos, aTextSize);
+ ImplSetFocusRect(aTOutRect);
+ DrawControlText(*pDev, aTOutRect, aText, nTextStyle, nullptr, nullptr, &aDeviceTextSize);
}
else
{
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 72ee5948a50e..92e16e66c86e 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -439,8 +439,8 @@ void Control::ImplInitSettings(const bool, const bool)
ApplySettings(*this);
}
-void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const OUString& _rStr,
- DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText ) const
+Rectangle Control::DrawControlText( OutputDevice& _rTargetDevice, const Rectangle& rRect, const OUString& _rStr,
+ DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText, const Size* i_pDeviceSize ) const
{
OUString rPStr = _rStr;
DrawTextFlags nPStyle = _nStyle;
@@ -456,14 +456,42 @@ void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRec
if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
{
- _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, rPStr, nPStyle );
- _rTargetDevice.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
+ const Rectangle aRet = _rTargetDevice.GetTextRect(rRect, rPStr, nPStyle);
+ _rTargetDevice.DrawText(aRet, rPStr, nPStyle, _pVector, _pDisplayText);
+ return aRet;
}
- else
+
+ ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
+ return aRenderer.DrawText(rRect, rPStr, nPStyle, _pVector, _pDisplayText, i_pDeviceSize);
+}
+
+Rectangle Control::GetControlTextRect( OutputDevice& _rTargetDevice, const Rectangle & rRect,
+ const OUString& _rStr, DrawTextFlags _nStyle, Size* o_pDeviceSize ) const
+{
+ OUString rPStr = _rStr;
+ DrawTextFlags nPStyle = _nStyle;
+
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
+ if (!accel || (autoacc && !mbShowAccelerator))
+ {
+ rPStr = GetNonMnemonicString( _rStr );
+ nPStyle &= ~DrawTextFlags::HideMnemonic;
+ }
+
+ if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
{
- ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
- _io_rRect = aRenderer.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
+ Rectangle aRet = _rTargetDevice.GetTextRect( rRect, rPStr, nPStyle );
+ if (o_pDeviceSize)
+ {
+ *o_pDeviceSize = aRet.GetSize();
+ }
+ return aRet;
}
+
+ ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
+ return aRenderer.GetTextRect(rRect, rPStr, nPStyle, o_pDeviceSize);
}
Font
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index 98532d8c4771..f90ee89c32d2 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -197,7 +197,7 @@ void FixedText::ImplDraw(OutputDevice* pDev, DrawFlags nDrawFlags,
if( bFillLayout )
(mpControlData->mpLayoutData->m_aDisplayText).clear();
- Rectangle aRect( Rectangle( aPos, rSize ) );
+ const Rectangle aRect(aPos, rSize);
DrawControlText(*pDev, aRect, aText, nTextStyle,
bFillLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : nullptr,
bFillLayout ? &mpControlData->mpLayoutData->m_aDisplayText : nullptr);
@@ -572,7 +572,7 @@ void FixedLine::ImplDraw(vcl::RenderContext& rRenderContext)
if (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono)
nStyle |= DrawTextFlags::Mono;
- DrawControlText(*this, aRect, aText, nStyle, nullptr, nullptr);
+ aRect = DrawControlText(*this, aRect, aText, nStyle, nullptr, nullptr);
long nTop = aRect.Top() + ((aRect.GetHeight() - 1) / 2);
aDecoView.DrawSeparator(Point(aRect.Right() + FIXEDLINE_TEXT_BORDER, nTop), Point(aOutSize.Width() - 1, nTop), false);
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index fd5d14f5e929..10253bca96f8 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -938,8 +938,8 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem* p
Color aOldColor(rRenderContext.GetTextColor());
rRenderContext.SetTextColor(aColor);
- Rectangle aOutRect(nXPos + aImageSize.Width(), nYPos,
- nXPos + aImageSize.Width() + nTextWidth, nYPos + nTextHeight);
+ const Rectangle aOutRect(nXPos + aImageSize.Width(), nYPos,
+ nXPos + aImageSize.Width() + nTextWidth, nYPos + nTextHeight);
DrawControlText(rRenderContext, aOutRect, pItem->maFormatText, nStyle,
nullptr, nullptr);
diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx
index a28eaf752e5c..4f459b6d33c9 100644
--- a/vcl/source/gdi/textlayout.cxx
+++ b/vcl/source/gdi/textlayout.cxx
@@ -84,8 +84,8 @@ namespace vcl
public:
// equivalents to the respective OutputDevice methods, which take the reference device into account
- long GetTextArray( const OUString& _rText, long* _pDXAry, sal_Int32 _nStartIndex, sal_Int32 _nLength ) const;
- Rectangle DrawText( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText );
+ Rectangle DrawText( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText, const Size* i_pDeviceSize );
+ Rectangle GetTextRect( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, Size* o_pDeviceSize );
protected:
void onBeginDrawText()
@@ -98,6 +98,8 @@ namespace vcl
}
private:
+ long GetTextArray( const OUString& _rText, long* _pDXAry, sal_Int32 _nStartIndex, sal_Int32 _nLength ) const;
+
OutputDevice& m_rTargetDevice;
OutputDevice& m_rReferenceDevice;
Font m_aUnzoomedPointFont;
@@ -252,7 +254,8 @@ namespace vcl
return true;
}
- Rectangle ReferenceDeviceTextLayout::DrawText( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText )
+ Rectangle ReferenceDeviceTextLayout::DrawText( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle,
+ MetricVector* _pVector, OUString* _pDisplayText, const Size* i_pDeviceSize )
{
if ( _rText.isEmpty() )
return Rectangle();
@@ -267,6 +270,13 @@ namespace vcl
// and the like in our ctor, we set the map mode of the target device from pixel to twip, but our caller doesn't know this,
// but passed pixel coordinates. So, adjust the rect.
Rectangle aRect( m_rTargetDevice.PixelToLogic( _rRect ) );
+ if (i_pDeviceSize)
+ {
+ //if i_pDeviceSize is passed in here, it was the original pre logic-to-pixel size of _rRect
+ SAL_WARN_IF(std::abs(_rRect.GetSize().Width() - m_rTargetDevice.LogicToPixel(*i_pDeviceSize).Width()) > 1, "vcl", "DeviceSize width was expected to match Pixel width");
+ SAL_WARN_IF(std::abs(_rRect.GetSize().Height() - m_rTargetDevice.LogicToPixel(*i_pDeviceSize).Height()) > 1, "vcl", "DeviceSize height was expected to match Pixel height");
+ aRect.SetSize(*i_pDeviceSize);
+ }
onBeginDrawText();
m_rTargetDevice.DrawText( aRect, _rText, _nStyle, _pVector, _pDisplayText, this );
@@ -302,6 +312,37 @@ namespace vcl
return aTextRect;
}
+ Rectangle ReferenceDeviceTextLayout::GetTextRect( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, Size* o_pDeviceSize )
+ {
+ if ( _rText.isEmpty() )
+ return Rectangle();
+
+ // determine text layout mode from the RTL-ness of the control whose text we render
+ ComplexTextLayoutMode nTextLayoutMode = m_bRTLEnabled ? TEXT_LAYOUT_BIDI_RTL : TEXT_LAYOUT_DEFAULT;
+ m_rReferenceDevice.SetLayoutMode( nTextLayoutMode );
+ m_rTargetDevice.SetLayoutMode( nTextLayoutMode | TEXT_LAYOUT_TEXTORIGIN_LEFT );
+
+ // TEXT_LAYOUT_TEXTORIGIN_LEFT is because when we do actually draw the text (in DrawText( Point, ... )), then
+ // our caller gives us the left border of the draw position, regardless of script type, text layout,
+ // and the like in our ctor, we set the map mode of the target device from pixel to twip, but our caller doesn't know this,
+ // but passed pixel coordinates. So, adjust the rect.
+ Rectangle aRect( m_rTargetDevice.PixelToLogic( _rRect ) );
+
+ Rectangle aTextRect = m_rTargetDevice.GetTextRect( aRect, _rText, _nStyle, nullptr, this );
+
+ //if o_pDeviceSize is available, stash the pre logic-to-pixel size in it
+ if (o_pDeviceSize)
+ {
+ *o_pDeviceSize = aTextRect.GetSize();
+ }
+
+ // similar to above, the text rect now contains TWIPs (or whatever unit the ref device has), but the caller
+ // expects pixel coordinates
+ aTextRect = m_rTargetDevice.LogicToPixel( aTextRect );
+
+ return aTextRect;
+ }
+
ControlTextRenderer::ControlTextRenderer( const Control& _rControl, OutputDevice& _rTargetDevice, OutputDevice& _rReferenceDevice )
:m_pImpl( new ReferenceDeviceTextLayout( _rControl, _rTargetDevice, _rReferenceDevice ) )
{
@@ -312,9 +353,14 @@ namespace vcl
}
Rectangle ControlTextRenderer::DrawText( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle,
- MetricVector* _pVector, OUString* _pDisplayText )
+ MetricVector* _pVector, OUString* _pDisplayText, const Size* i_pDeviceSize )
+ {
+ return m_pImpl->DrawText( _rRect, _rText, _nStyle, _pVector, _pDisplayText, i_pDeviceSize );
+ }
+
+ Rectangle ControlTextRenderer::GetTextRect( const Rectangle& _rRect, const OUString& _rText, DrawTextFlags _nStyle, Size* o_pDeviceSize = nullptr )
{
- return m_pImpl->DrawText( _rRect, _rText, _nStyle, _pVector, _pDisplayText );
+ return m_pImpl->GetTextRect( _rRect, _rText, _nStyle, o_pDeviceSize );
}
} // namespace vcl