summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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