summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/control/button.cxx175
-rw-r--r--vcl/source/control/combobox.cxx6
-rw-r--r--vcl/source/control/ctrl.cxx189
-rw-r--r--vcl/source/control/edit.cxx20
-rw-r--r--vcl/source/control/fixed.cxx108
-rw-r--r--vcl/source/control/group.cxx44
-rw-r--r--vcl/source/control/ilstbox.cxx40
-rw-r--r--vcl/source/control/lstbox.cxx6
-rw-r--r--vcl/source/control/spinfld.cxx4
-rw-r--r--vcl/source/control/tabctrl.cxx74
-rw-r--r--vcl/source/fontsubset/cff.cxx78
-rw-r--r--vcl/source/gdi/bitmapex.cxx73
-rw-r--r--vcl/source/gdi/makefile.mk82
-rw-r--r--vcl/source/gdi/outdev3.cxx182
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx5
-rwxr-xr-xvcl/source/gdi/sallayout.cxx8
-rwxr-xr-xvcl/source/gdi/textlayout.cxx384
-rw-r--r--vcl/source/window/status.cxx7
-rw-r--r--vcl/source/window/window.cxx2
19 files changed, 1022 insertions, 465 deletions
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index e7a4aadb8694..53a060af6bd6 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -50,7 +50,7 @@
#include <tools/poly.hxx>
#include <vcl/button.hxx>
#include <vcl/window.h>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#ifndef _SV_NATIVEWIDGET_HXX
#include <vcl/salnativewidgets.hxx>
#endif
@@ -383,8 +383,8 @@ void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos,
WinBits nWinStyle = GetStyle();
Rectangle aOutRect( rPos, rSize );
- MetricVector *pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String *pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
+ MetricVector *pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String *pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
ImageAlign eImageAlign = mpButtonData->meImageAlign;
Size aImageSize = mpButtonData->maImage.GetSizePixel();
@@ -406,13 +406,12 @@ void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos,
}
else if ( bDrawText && !bDrawImage && !bHasSymbol )
{
- aOutRect = pDev->GetTextRect( aOutRect, aText, nTextStyle );
- rSize = aOutRect.GetSize();
- rPos = aOutRect.TopLeft();
+ DrawControlText( *pDev, aOutRect, aText, nTextStyle, pVector, pDisplayText );
ImplSetFocusRect( aOutRect );
+ rSize = aOutRect.GetSize();
+ rPos = aOutRect.TopLeft();
- pDev->DrawText( aOutRect, aText, nTextStyle, pVector, pDisplayText );
return;
}
@@ -853,31 +852,25 @@ WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& PushButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetPushButtonFont();
+}
+
+// -----------------------------------------------------------------
+const Color& PushButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetButtonTextColor();
+}
+
// -----------------------------------------------------------------------
void PushButton::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetPushButtonFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetButtonTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Button::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -1659,7 +1652,7 @@ void PushButton::KeyUp( const KeyEvent& rKEvt )
void PushButton::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<PushButton*>(this)->ImplDrawPushButton( true );
}
@@ -2225,31 +2218,25 @@ WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetRadioCheckFont();
+}
+
+// -----------------------------------------------------------------
+const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetRadioCheckTextColor();
+}
+
// -----------------------------------------------------------------------
void RadioButton::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetRadioCheckFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetRadioCheckTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Button::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -2424,16 +2411,14 @@ if ( bNativeOK == FALSE )
void RadioButton::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
const Point& rPos, const Size& rSize,
- const Size& rImageSize, long nImageSep,
- Rectangle& rStateRect,
- Rectangle& rMouseRect,
- bool bLayout )
+ const Size& rImageSize, Rectangle& rStateRect,
+ Rectangle& rMouseRect, bool bLayout )
{
WinBits nWinStyle = GetStyle();
XubString aText( GetText() );
Rectangle aRect( rPos, rSize );
- MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
+ MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
pDev->Push( PUSH_CLIPREGION );
pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
@@ -2446,9 +2431,9 @@ void RadioButton::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
{
USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
+ const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
Size aSize( rSize );
Point aPos( rPos );
-
aPos.X() += rImageSize.Width() + nImageSep;
aSize.Width() -= rImageSize.Width() + nImageSep;
@@ -2578,7 +2563,7 @@ void RadioButton::ImplDrawRadioButton( bool bLayout )
// Draw control text
ImplDraw( this, 0, Point(), GetOutputSizePixel(),
- aImageSize, IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
+ aImageSize, maStateRect, maMouseRect, bLayout );
if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==TRUE) )
{
@@ -2854,7 +2839,7 @@ void RadioButton::KeyUp( const KeyEvent& rKEvt )
void RadioButton::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
}
@@ -2909,8 +2894,7 @@ void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize
pDev->SetTextFillColor();
ImplDraw( pDev, nFlags, aPos, aSize,
- aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
- aStateRect, aMouseRect );
+ aImageSize, aStateRect, aMouseRect );
Point aCenterPos = aStateRect.Center();
long nRadX = aImageSize.Width()/2;
@@ -3158,6 +3142,15 @@ void RadioButton::Check( BOOL bCheck )
// -----------------------------------------------------------------------
+long RadioButton::ImplGetImageToTextDistance() const
+{
+ // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
+ // which might have been aligned with the text of the check box
+ return CalcZoom( 4 );
+}
+
+// -----------------------------------------------------------------------
+
Size RadioButton::ImplGetRadioImageSize() const
{
Size aSize;
@@ -3331,12 +3324,12 @@ Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
{
// subtract what will be added later
nMaxWidth-=2;
- nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
+ nMaxWidth -= ImplGetImageToTextDistance();
Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
aSize.Width()+=2; // for focus rect
- aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
+ aSize.Width() += ImplGetImageToTextDistance();
aSize.Width() += aTextSize.Width();
if ( aSize.Height() < aTextSize.Height() )
aSize.Height() = aTextSize.Height();
@@ -3395,31 +3388,25 @@ WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetRadioCheckFont();
+}
+
+// -----------------------------------------------------------------
+const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetRadioCheckTextColor();
+}
+
// -----------------------------------------------------------------------
void CheckBox::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetRadioCheckFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetRadioCheckTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Button::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -3527,9 +3514,8 @@ void CheckBox::ImplDrawCheckBoxState()
void CheckBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
const Point& rPos, const Size& rSize,
- const Size& rImageSize, long nImageSep,
- Rectangle& rStateRect, Rectangle& rMouseRect,
- bool bLayout )
+ const Size& rImageSize, Rectangle& rStateRect,
+ Rectangle& rMouseRect, bool bLayout )
{
WinBits nWinStyle = GetStyle();
XubString aText( GetText() );
@@ -3543,6 +3529,7 @@ void CheckBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
{
USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
+ const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
Size aSize( rSize );
Point aPos( rPos );
aPos.X() += rImageSize.Width() + nImageSep;
@@ -3640,7 +3627,7 @@ void CheckBox::ImplDrawCheckBox( bool bLayout )
HideFocus();
ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
- IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
+ maStateRect, maMouseRect, bLayout );
if( !bLayout )
{
@@ -3797,7 +3784,7 @@ void CheckBox::KeyUp( const KeyEvent& rKEvt )
void CheckBox::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
}
@@ -3852,8 +3839,7 @@ void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
pDev->SetTextFillColor();
ImplDraw( pDev, nFlags, aPos, aSize,
- aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
- aStateRect, aMouseRect, false );
+ aImageSize, aStateRect, aMouseRect, false );
pDev->SetLineColor();
pDev->SetFillColor( Color( COL_BLACK ) );
@@ -4099,6 +4085,15 @@ void CheckBox::EnableTriState( BOOL bTriState )
// -----------------------------------------------------------------------
+long CheckBox::ImplGetImageToTextDistance() const
+{
+ // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
+ // which might have been aligned with the text of the check box
+ return CalcZoom( 4 );
+}
+
+// -----------------------------------------------------------------------
+
Size CheckBox::ImplGetCheckImageSize() const
{
Size aSize;
@@ -4232,12 +4227,12 @@ Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
{
// subtract what will be added later
nMaxWidth-=2;
- nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
+ nMaxWidth -= ImplGetImageToTextDistance();
Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
aSize.Width()+=2; // for focus rect
- aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
+ aSize.Width() += ImplGetImageToTextDistance();
aSize.Width() += aTextSize.Width();
if ( aSize.Height() < aTextSize.Height() )
aSize.Height() = aTextSize.Height();
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index f83e46e38302..21707d0182f5 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -44,7 +44,7 @@
#include <vcl/subedit.hxx>
#include <vcl/event.hxx>
#include <vcl/combobox.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
@@ -689,7 +689,7 @@ void ComboBox::Resize()
void ComboBox::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
AppendLayoutData( *mpSubEdit );
mpSubEdit->SetLayoutDataParent( this );
Control* pMainWindow = mpImplLB->GetMainWindow();
@@ -1534,7 +1534,7 @@ void ComboBox::SetBorderStyle( USHORT nBorderStyle )
long ComboBox::GetIndexForPoint( const Point& rPoint, USHORT& rPos ) const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
// check whether rPoint fits at all
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 55c979fbd69f..1800327df33c 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -39,10 +39,12 @@
#include <vcl/event.hxx>
#include <vcl/ctrl.hxx>
#include <vcl/decoview.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#include <vcl/salnativewidgets.hxx>
+#include <vcl/textlayout.hxx>
-
+#include <comphelper/processfactory.hxx>
+#include <tools/diagnose_ex.h>
using namespace vcl;
@@ -51,7 +53,7 @@ using namespace vcl;
void Control::ImplInitControlData()
{
mbHasFocus = FALSE;
- mpLayoutData = NULL;
+ mpControlData = new ImplControlData;
}
// -----------------------------------------------------------------------
@@ -90,7 +92,7 @@ Control::Control( Window* pParent, const ResId& rResId ) :
Control::~Control()
{
- delete mpLayoutData, mpLayoutData = NULL;
+ delete mpControlData, mpControlData = NULL;
}
// -----------------------------------------------------------------------
@@ -111,7 +113,7 @@ void Control::LoseFocus()
void Control::Resize()
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
Window::Resize();
}
@@ -123,10 +125,31 @@ void Control::FillLayoutData() const
// -----------------------------------------------------------------------
+void Control::CreateLayoutData() const
+{
+ DBG_ASSERT( !mpControlData->mpLayoutData, "Control::CreateLayoutData: should be called with non-existent layout data only!" );
+ mpControlData->mpLayoutData = new ::vcl::ControlLayoutData();
+}
+
+// -----------------------------------------------------------------------
+
+bool Control::HasLayoutData() const
+{
+ return mpControlData->mpLayoutData != NULL;
+}
+
+// -----------------------------------------------------------------------
+
+::vcl::ControlLayoutData* Control::GetLayoutData() const
+{
+ return mpControlData->mpLayoutData;
+}
+
+// -----------------------------------------------------------------------
+
void Control::SetText( const String& rStr )
{
- delete mpLayoutData;
- mpLayoutData = NULL;
+ ImplClearLayoutData();
Window::SetText( rStr );
}
@@ -142,9 +165,9 @@ Rectangle ControlLayoutData::GetCharacterBounds( long nIndex ) const
Rectangle Control::GetCharacterBounds( long nIndex ) const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->GetCharacterBounds( nIndex ) : Rectangle();
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetCharacterBounds( nIndex ) : Rectangle();
}
// -----------------------------------------------------------------------
@@ -167,9 +190,9 @@ long ControlLayoutData::GetIndexForPoint( const Point& rPoint ) const
long Control::GetIndexForPoint( const Point& rPoint ) const
{
- if( ! mpLayoutData )
+ if( ! HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->GetIndexForPoint( rPoint ) : -1;
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetIndexForPoint( rPoint ) : -1;
}
// -----------------------------------------------------------------------
@@ -186,9 +209,9 @@ long ControlLayoutData::GetLineCount() const
long Control::GetLineCount() const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->GetLineCount() : 0;
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineCount() : 0;
}
// -----------------------------------------------------------------------
@@ -220,9 +243,9 @@ Pair ControlLayoutData::GetLineStartEnd( long nLine ) const
Pair Control::GetLineStartEnd( long nLine ) const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->GetLineStartEnd( nLine ) : Pair( -1, -1 );
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineStartEnd( nLine ) : Pair( -1, -1 );
}
// -----------------------------------------------------------------------
@@ -263,18 +286,18 @@ long ControlLayoutData::ToRelativeLineIndex( long nIndex ) const
long Control::ToRelativeLineIndex( long nIndex ) const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->ToRelativeLineIndex( nIndex ) : -1;
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->ToRelativeLineIndex( nIndex ) : -1;
}
// -----------------------------------------------------------------------
String Control::GetDisplayText() const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
- return mpLayoutData ? mpLayoutData->m_aDisplayText : GetText();
+ return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->m_aDisplayText : GetText();
}
// -----------------------------------------------------------------------
@@ -321,8 +344,7 @@ void Control::StateChanged( StateChangedType nStateChange )
nStateChange == STATE_CHANGE_CONTROLFONT
)
{
- delete mpLayoutData;
- mpLayoutData = NULL;
+ ImplClearLayoutData();
}
Window::StateChanged( nStateChange );
}
@@ -331,25 +353,25 @@ void Control::StateChanged( StateChangedType nStateChange )
void Control::AppendLayoutData( const Control& rSubControl ) const
{
- if( ! rSubControl.mpLayoutData )
+ if( !rSubControl.HasLayoutData() )
rSubControl.FillLayoutData();
- if( ! rSubControl.mpLayoutData || ! rSubControl.mpLayoutData->m_aDisplayText.Len() )
+ if( !rSubControl.HasLayoutData() || !rSubControl.mpControlData->mpLayoutData->m_aDisplayText.Len() )
return;
- long nCurrentIndex = mpLayoutData->m_aDisplayText.Len();
- mpLayoutData->m_aDisplayText.Append( rSubControl.mpLayoutData->m_aDisplayText );
- int nLines = rSubControl.mpLayoutData->m_aLineIndices.size();
+ long nCurrentIndex = mpControlData->mpLayoutData->m_aDisplayText.Len();
+ mpControlData->mpLayoutData->m_aDisplayText.Append( rSubControl.mpControlData->mpLayoutData->m_aDisplayText );
+ int nLines = rSubControl.mpControlData->mpLayoutData->m_aLineIndices.size();
int n;
- mpLayoutData->m_aLineIndices.push_back( nCurrentIndex );
+ mpControlData->mpLayoutData->m_aLineIndices.push_back( nCurrentIndex );
for( n = 1; n < nLines; n++ )
- mpLayoutData->m_aLineIndices.push_back( rSubControl.mpLayoutData->m_aLineIndices[n] + nCurrentIndex );
- int nRectangles = rSubControl.mpLayoutData->m_aUnicodeBoundRects.size();
+ mpControlData->mpLayoutData->m_aLineIndices.push_back( rSubControl.mpControlData->mpLayoutData->m_aLineIndices[n] + nCurrentIndex );
+ int nRectangles = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects.size();
Rectangle aRel = const_cast<Control&>(rSubControl).GetWindowExtentsRelative( const_cast<Control*>(this) );
for( n = 0; n < nRectangles; n++ )
{
- Rectangle aRect = rSubControl.mpLayoutData->m_aUnicodeBoundRects[n];
+ Rectangle aRect = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects[n];
aRect.Move( aRel.Left(), aRel.Top() );
- mpLayoutData->m_aUnicodeBoundRects.push_back( aRect );
+ mpControlData->mpLayoutData->m_aUnicodeBoundRects.push_back( aRect );
}
}
@@ -378,15 +400,15 @@ BOOL Control::ImplCallEventListenersAndHandler( ULONG nEvent, const Link& rHand
void Control::SetLayoutDataParent( const Control* pParent ) const
{
- if( mpLayoutData )
- mpLayoutData->m_pParent = pParent;
+ if( HasLayoutData() )
+ mpControlData->mpLayoutData->m_pParent = pParent;
}
// -----------------------------------------------------------------
void Control::ImplClearLayoutData() const
{
- delete mpLayoutData, mpLayoutData = NULL;
+ delete mpControlData->mpLayoutData, mpControlData->mpLayoutData = NULL;
}
// -----------------------------------------------------------------------
@@ -467,3 +489,102 @@ Size Control::GetOptimalSize(WindowSizeType eType) const
return Size( LONG_MAX, LONG_MAX );
}
}
+
+// -----------------------------------------------------------------
+
+void Control::SetReferenceDevice( OutputDevice* _referenceDevice )
+{
+ if ( mpControlData->mpReferenceDevice == _referenceDevice )
+ return;
+
+ mpControlData->mpReferenceDevice = _referenceDevice;
+ Invalidate();
+}
+
+// -----------------------------------------------------------------
+
+OutputDevice* Control::GetReferenceDevice() const
+{
+ return mpControlData->mpReferenceDevice;
+}
+
+// -----------------------------------------------------------------
+
+const Font& Control::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetLabelFont();
+}
+
+// -----------------------------------------------------------------
+const Color& Control::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetLabelTextColor();
+}
+
+// -----------------------------------------------------------------
+void Control::ImplInitSettings( const BOOL _bFont, const BOOL _bForeground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( _bFont )
+ {
+ Font aFont( GetCanonicalFont( rStyleSettings ) );
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( _bForeground || _bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = GetCanonicalTextColor( rStyleSettings );
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+}
+
+// -----------------------------------------------------------------
+
+void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const XubString& _rStr,
+ USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText ) const
+{
+#ifdef FS_DEBUG
+ if ( !_pVector )
+ {
+ static MetricVector aCharRects;
+ static String sDisplayText;
+ aCharRects.clear();
+ sDisplayText = String();
+ _pVector = &aCharRects;
+ _pDisplayText = &sDisplayText;
+ }
+#endif
+
+ if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
+ {
+ _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, _rStr, _nStyle );
+ _rTargetDevice.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+ }
+ else
+ {
+ ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
+ _io_rRect = aRenderer.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+ }
+
+#ifdef FS_DEBUG
+ _rTargetDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ _rTargetDevice.SetLineColor( COL_LIGHTRED );
+ _rTargetDevice.SetFillColor();
+ for ( MetricVector::const_iterator cr = _pVector->begin();
+ cr != _pVector->end();
+ ++cr
+ )
+ {
+ _rTargetDevice.DrawRect( *cr );
+ }
+ _rTargetDevice.Pop();
+#endif
+}
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index 5f41a441c6a1..b654e034470f 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -47,7 +47,7 @@
#include <vcl/subedit.hxx>
#include <vcl/edit.hxx>
#include <vcl/svapp.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/window.h>
@@ -409,7 +409,7 @@ void Edit::ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground )
if ( IsControlFont() )
aFont.Merge( GetControlFont() );
SetZoomedPointFont( aFont );
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
}
if ( bFont || bForeground )
@@ -526,8 +526,8 @@ void Edit::ImplRepaint( xub_StrLen nStart, xub_StrLen nEnd, bool bLayout )
long nPos = nStart ? pDX[2*nStart] : 0;
aPos.X() = nPos + mnXOffset + ImplGetExtraOffset();
- MetricVector* pVector = &mpLayoutData->m_aUnicodeBoundRects;
- String* pDisplayText = &mpLayoutData->m_aDisplayText;
+ MetricVector* pVector = &mpControlData->mpLayoutData->m_aUnicodeBoundRects;
+ String* pDisplayText = &mpControlData->mpLayoutData->m_aDisplayText;
DrawText( aPos, aText, nStart, nEnd - nStart, pVector, pDisplayText );
@@ -722,7 +722,7 @@ void Edit::ImplDelete( const Selection& rSelection, BYTE nDirection, BYTE nMode
((rSelection.Max() == aText.Len()) && (nDirection == EDIT_DEL_RIGHT))) )
return;
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
Selection aSelection( rSelection );
aSelection.Justify();
@@ -864,7 +864,7 @@ void Edit::ImplInsertText( const XubString& rStr, const Selection* pNewSel, sal_
rtl::OUString aNewText( ImplGetValidString( rStr ) );
ImplTruncateToMaxLen( aNewText, aSelection.Len() );
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
if ( aSelection.Len() )
maText.Erase( (xub_StrLen)aSelection.Min(), (xub_StrLen)aSelection.Len() );
@@ -1006,7 +1006,7 @@ void Edit::ImplSetText( const XubString& rText, const Selection* pNewSelection )
// wird, dann InsertText, damit flackerfrei.
if ( ( rText.Len() <= mnMaxTextLen ) && ( (rText != maText) || (pNewSelection && (*pNewSelection != maSelection)) ) )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
maSelection.Min() = 0;
maSelection.Max() = maText.Len();
if ( mnXOffset || HasPaintEvent() )
@@ -1637,7 +1637,7 @@ BOOL Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt )
{
if ( !rKEvt.GetKeyCode().IsMod2() )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
Selection aSel( maSelection );
@@ -1858,7 +1858,7 @@ void Edit::KeyInput( const KeyEvent& rKEvt )
void Edit::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<Edit*>(this)->ImplRepaint( 0, STRING_LEN, true );
}
@@ -2648,7 +2648,7 @@ void Edit::ImplSetSelection( const Selection& rSelection, BOOL bPaint )
if ( aNew != maSelection )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
maSelection = aNew;
if ( bPaint && ( aOld.Len() || aNew.Len() || IsPaintTransparent() ) )
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index ecb066d107ce..3d19e288a1ce 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -33,7 +33,7 @@
#include <vcl/decoview.hxx>
#include <vcl/event.hxx>
#include <vcl/fixed.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#include <vcl/window.h>
#include <tools/rc.h>
@@ -109,40 +109,25 @@ WinBits FixedText::ImplInitStyle( WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& FixedText::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return ( GetStyle() & WB_INFO ) ? _rStyle.GetInfoFont() : _rStyle.GetLabelFont();
+}
+
+// -----------------------------------------------------------------
+const Color& FixedText::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return ( GetStyle() & WB_INFO ) ? _rStyle.GetInfoTextColor() : _rStyle.GetLabelTextColor();
+}
+
// -----------------------------------------------------------------------
void FixedText::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont;
- if ( GetStyle() & WB_INFO )
- aFont = rStyleSettings.GetInfoFont();
- else
- aFont = rStyleSettings.GetLabelFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- {
- if ( GetStyle() & WB_INFO )
- aColor = rStyleSettings.GetInfoTextColor();
- else
- aColor = rStyleSettings.GetLabelTextColor();
- }
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Control::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -278,17 +263,13 @@ void FixedText::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
nTextStyle |= TEXT_DRAW_MONO;
if( bFillLayout )
- {
- mpLayoutData->m_aDisplayText = String();
- pDev->DrawText( Rectangle( aPos, rSize ),
- aText,
- nTextStyle,
- &mpLayoutData->m_aUnicodeBoundRects,
- &mpLayoutData->m_aDisplayText
- );
- }
- else
- pDev->DrawText( Rectangle( aPos, rSize ), aText, nTextStyle );
+ mpControlData->mpLayoutData->m_aDisplayText = String();
+
+ Rectangle aRect( Rectangle( aPos, rSize ) );
+ DrawControlText( *pDev, aRect, aText, nTextStyle,
+ bFillLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL,
+ bFillLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL
+ );
}
// -----------------------------------------------------------------------
@@ -446,7 +427,7 @@ Size FixedText::GetOptimalSize(WindowSizeType eType) const
void FixedText::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
ImplDraw( const_cast<FixedText*>(this), 0, Point(), GetOutputSizePixel(), true );
}
@@ -468,31 +449,25 @@ WinBits FixedLine::ImplInitStyle( WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& FixedLine::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetGroupFont();
+}
+
+// -----------------------------------------------------------------
+const Color& FixedLine::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetGroupTextColor();
+}
+
// -----------------------------------------------------------------------
void FixedLine::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetGroupFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetGroupTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Control::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -526,8 +501,8 @@ void FixedLine::ImplDraw( bool bLayout )
String aText = GetText();
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
WinBits nWinStyle = GetStyle();
- MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
+ MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
SetLineColor( Color( COL_BLACK ) );
@@ -574,8 +549,7 @@ void FixedLine::ImplDraw( bool bLayout )
if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
nStyle |= TEXT_DRAW_MONO;
- aRect = GetTextRect( aRect, aText, nStyle );
- DrawText( aRect, aText, nStyle, pVector, pDisplayText );
+ DrawControlText( *this, aRect, aText, nStyle, pVector, pDisplayText );
if( !pVector )
{
@@ -617,7 +591,7 @@ FixedLine::FixedLine( Window* pParent, const ResId& rResId ) :
void FixedLine::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<FixedLine*>(this)->ImplDraw( true );
}
diff --git a/vcl/source/control/group.cxx b/vcl/source/control/group.cxx
index a844c2f2eb93..4adc91f88d84 100644
--- a/vcl/source/control/group.cxx
+++ b/vcl/source/control/group.cxx
@@ -32,7 +32,7 @@
#include "precompiled_vcl.hxx"
#include <vcl/event.hxx>
#include <vcl/group.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#ifndef _SV_RC_H
#include <tools/rc.h>
@@ -66,31 +66,25 @@ WinBits GroupBox::ImplInitStyle( WinBits nStyle )
return nStyle;
}
+// -----------------------------------------------------------------
+
+const Font& GroupBox::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetGroupFont();
+}
+
+// -----------------------------------------------------------------
+const Color& GroupBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetGroupTextColor();
+}
+
// -----------------------------------------------------------------------
void GroupBox::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetGroupFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetGroupTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Control::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -227,16 +221,16 @@ void GroupBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
}
}
- MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
- pDev->DrawText( aRect, aText, nTextStyle, pVector, pDisplayText );
+ MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
+ DrawControlText( *pDev, aRect, aText, nTextStyle, pVector, pDisplayText );
}
// -----------------------------------------------------------------------
void GroupBox::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<GroupBox*>(this)-> ImplDraw( const_cast<GroupBox*>(this), 0, Point(), GetOutputSizePixel(), true );
}
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index c0a28c8b03fd..a915d8e6b9e8 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -40,7 +40,7 @@
#include <vcl/lstbox.h>
#include <vcl/ilstbox.hxx>
#include <vcl/i18nhelp.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#include <vcl/unohelp.hxx>
#ifndef _COM_SUN_STAR_UTIL_XCOLLATOR_HPP_
#include <com/sun/star/i18n/XCollator.hpp>
@@ -647,7 +647,7 @@ void ImplListBoxWindow::Clear()
mnTop = 0;
mnLeft = 0;
mbImgsDiffSz = FALSE;
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
@@ -656,7 +656,7 @@ void ImplListBoxWindow::Clear()
void ImplListBoxWindow::SetUserItemSize( const Size& rSz )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
maUserItemSize = rSz;
ImplCalcMetrics();
}
@@ -778,7 +778,7 @@ void ImplListBoxWindow::ImplCallSelect()
nMRUCount--;
}
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
ImplEntryType* pNewEntry = new ImplEntryType( aSelected );
pNewEntry->mbIsSelected = bSelectNewEntry;
@@ -798,7 +798,7 @@ void ImplListBoxWindow::ImplCallSelect()
USHORT ImplListBoxWindow::InsertEntry( USHORT nPos, ImplEntryType* pNewEntry )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
USHORT nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort );
if( (GetStyle() & WB_WORDBREAK) )
@@ -812,7 +812,7 @@ USHORT ImplListBoxWindow::InsertEntry( USHORT nPos, ImplEntryType* pNewEntry )
void ImplListBoxWindow::RemoveEntry( USHORT nPos )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
mpEntryList->RemoveEntry( nPos );
if( mnCurrentPos >= mpEntryList->GetEntryCount() )
mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
@@ -1062,7 +1062,7 @@ void ImplListBoxWindow::SelectEntry( USHORT nPos, BOOL bSelect )
ImplPaint( nPos );
if ( !IsVisible( nPos ) )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
USHORT nVisibleEntries = GetLastVisibleEntry()-mnTop;
if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
{
@@ -1233,7 +1233,7 @@ BOOL ImplListBoxWindow::SelectEntries( USHORT nSelect, LB_EVENT_TYPE eLET, BOOL
if( HasFocus() )
ImplShowFocusRect();
}
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
}
return bSelectionChanged;
}
@@ -1838,8 +1838,8 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
if( bDrawText )
{
- MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
+ MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
XubString aStr( mpEntryList->GetEntryText( nPos ) );
if ( aStr.Len() )
{
@@ -1859,7 +1859,7 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
}
if( bLayout )
- mpLayoutData->m_aLineIndices.push_back( mpLayoutData->m_aDisplayText.Len() );
+ mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );
// pb: #106948# explicit mirroring for calc
if ( mbMirroring )
@@ -1900,7 +1900,7 @@ void ImplListBoxWindow::DrawEntry( USHORT nPos, BOOL bDrawImage, BOOL bDrawText,
void ImplListBoxWindow::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<ImplListBoxWindow*>(this)->
ImplDoPaint( Rectangle( Point( 0, 0 ), GetOutputSize() ), true );
}
@@ -1978,7 +1978,7 @@ void ImplListBoxWindow::Resize()
if ( bShowFocusRect )
ImplShowFocusRect();
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
}
// -----------------------------------------------------------------------
@@ -2034,7 +2034,7 @@ void ImplListBoxWindow::SetTopEntry( USHORT nTop )
if ( nTop != mnTop )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 );
Update();
ImplHideFocusRect();
@@ -2078,7 +2078,7 @@ void ImplListBoxWindow::ScrollHorz( long n )
if ( nDiff )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
mnLeft = sal::static_int_cast<USHORT>(mnLeft + nDiff);
Update();
ImplHideFocusRect();
@@ -2148,7 +2148,7 @@ void ImplListBoxWindow::StateChanged( StateChangedType nType )
ImplInitSettings( FALSE, FALSE, TRUE );
Invalidate();
}
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
}
// -----------------------------------------------------------------------
@@ -2162,7 +2162,7 @@ void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt )
((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
(rDCEvt.GetFlags() & SETTINGS_STYLE)) )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
ImplInitSettings( TRUE, TRUE, TRUE );
ImplCalcMetrics();
Invalidate();
@@ -2743,7 +2743,7 @@ void ImplWin::MouseButtonDown( const MouseEvent& )
void ImplWin::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const_cast<ImplWin*>(this)->ImplDraw( true );
}
@@ -2936,8 +2936,8 @@ void ImplWin::DrawEntry( BOOL bDrawImage, BOOL bDrawText, BOOL bDrawTextAtImageP
aTextRect.Left() += nMaxWidth + IMG_TXT_DISTANCE;
}
- MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
- String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
+ MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
+ String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText );
}
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index a4d3cbc22544..ceabbe4ab166 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -43,7 +43,7 @@
#include "vcl/ilstbox.hxx"
#include "vcl/lstbox.hxx"
#include "vcl/combobox.hxx"
-#include "vcl/controllayout.hxx"
+#include "vcl/controldata.hxx"
#include "tools/debug.hxx"
@@ -719,7 +719,7 @@ void ListBox::Resize()
void ListBox::FillLayoutData() const
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
const Control* pMainWin = mpImplLB->GetMainWindow();
if( mpFloatWin )
{
@@ -743,7 +743,7 @@ void ListBox::FillLayoutData() const
long ListBox::GetIndexForPoint( const Point& rPoint, USHORT& rPos ) const
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
FillLayoutData();
// check whether rPoint fits at all
diff --git a/vcl/source/control/spinfld.cxx b/vcl/source/control/spinfld.cxx
index 0d656da40ba7..1cdaa39298df 100644
--- a/vcl/source/control/spinfld.cxx
+++ b/vcl/source/control/spinfld.cxx
@@ -36,7 +36,7 @@
#include "vcl/decoview.hxx"
#include "vcl/spin.h"
#include "vcl/spinfld.hxx"
-#include "vcl/controllayout.hxx"
+#include "vcl/controldata.hxx"
#include "vcl/svdata.hxx"
// =======================================================================
@@ -637,7 +637,7 @@ void SpinField::FillLayoutData() const
{
if( mbSpin )
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
AppendLayoutData( *GetSubEdit() );
GetSubEdit()->SetLayoutDataParent( this );
}
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 561d550b1168..9a34629ddf8e 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -45,7 +45,7 @@
#include <vcl/button.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
-#include <vcl/controllayout.hxx>
+#include <vcl/controldata.hxx>
#include <vcl/sound.hxx>
#include <vcl/window.h>
@@ -169,31 +169,25 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle )
EnableChildTransparentMode( TRUE );
}
+// -----------------------------------------------------------------
+
+const Font& TabControl::GetCanonicalFont( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetAppFont();
+}
+
+// -----------------------------------------------------------------
+const Color& TabControl::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
+{
+ return _rStyle.GetButtonTextColor();
+}
+
// -----------------------------------------------------------------------
void TabControl::ImplInitSettings( BOOL bFont,
BOOL bForeground, BOOL bBackground )
{
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
-
- if ( bFont )
- {
- Font aFont = rStyleSettings.GetAppFont();
- if ( IsControlFont() )
- aFont.Merge( GetControlFont() );
- SetZoomedPointFont( aFont );
- }
-
- if ( bForeground || bFont )
- {
- Color aColor;
- if ( IsControlForeground() )
- aColor = GetControlForeground();
- else
- aColor = rStyleSettings.GetButtonTextColor();
- SetTextColor( aColor );
- SetTextFillColor();
- }
+ Control::ImplInitSettings( bFont, bForeground );
if ( bBackground )
{
@@ -232,9 +226,9 @@ void TabControl::ImplInitSettings( BOOL bFont,
void TabControl::ImplFreeLayoutData()
{
- if( mpLayoutData )
+ if( HasLayoutData() )
{
- delete mpLayoutData, mpLayoutData = NULL;
+ ImplClearLayoutData();
mpTabCtrlData->maLayoutPageIdToLine.clear();
mpTabCtrlData->maLayoutLineToPageId.clear();
}
@@ -864,9 +858,9 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo
if( bLayout )
{
- if( ! mpLayoutData )
+ if( !HasLayoutData() )
{
- mpLayoutData = new vcl::ControlLayoutData();
+ mpControlData->mpLayoutData = new vcl::ControlLayoutData();
mpTabCtrlData->maLayoutLineToPageId.clear();
mpTabCtrlData->maLayoutPageIdToLine.clear();
mpTabCtrlData->maTabRectangles.clear();
@@ -1010,8 +1004,8 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo
if( bLayout )
{
- int nLine = mpLayoutData->m_aLineIndices.size();
- mpLayoutData->m_aLineIndices.push_back( mpLayoutData->m_aDisplayText.Len() );
+ int nLine = mpControlData->mpLayoutData->m_aLineIndices.size();
+ mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );
mpTabCtrlData->maLayoutPageIdToLine[ (int)pItem->mnId ] = nLine;
mpTabCtrlData->maLayoutLineToPageId[ nLine ] = (int)pItem->mnId;
mpTabCtrlData->maTabRectangles.push_back( aRect );
@@ -1044,8 +1038,8 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo
DrawCtrlText( Point( nXPos + aImageSize.Width(), nYPos ),
pItem->maFormatText,
0, STRING_LEN, nStyle,
- bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL,
- bLayout ? &mpLayoutData->m_aDisplayText : NULL
+ bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL,
+ bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL
);
}
@@ -2108,17 +2102,17 @@ Rectangle TabControl::GetCharacterBounds( USHORT nPageId, long nIndex ) const
{
Rectangle aRet;
- if( ! mpLayoutData || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
+ if( !HasLayoutData() || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
FillLayoutData();
- if( mpLayoutData )
+ if( HasLayoutData() )
{
std::hash_map< int, int >::const_iterator it = mpTabCtrlData->maLayoutPageIdToLine.find( (int)nPageId );
if( it != mpTabCtrlData->maLayoutPageIdToLine.end() )
{
- Pair aPair = mpLayoutData->GetLineStartEnd( it->second );
+ Pair aPair = mpControlData->mpLayoutData->GetLineStartEnd( it->second );
if( (aPair.B() - aPair.A()) >= nIndex )
- aRet = mpLayoutData->GetCharacterBounds( aPair.A() + nIndex );
+ aRet = mpControlData->mpLayoutData->GetCharacterBounds( aPair.A() + nIndex );
}
}
@@ -2131,20 +2125,20 @@ long TabControl::GetIndexForPoint( const Point& rPoint, USHORT& rPageId ) const
{
long nRet = -1;
- if( ! mpLayoutData || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
+ if( !HasLayoutData() || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
FillLayoutData();
- if( mpLayoutData )
+ if( HasLayoutData() )
{
- int nIndex = mpLayoutData->GetIndexForPoint( rPoint );
+ int nIndex = mpControlData->mpLayoutData->GetIndexForPoint( rPoint );
if( nIndex != -1 )
{
// what line (->pageid) is this index in ?
- int nLines = mpLayoutData->GetLineCount();
+ int nLines = mpControlData->mpLayoutData->GetLineCount();
int nLine = -1;
while( ++nLine < nLines )
{
- Pair aPair = mpLayoutData->GetLineStartEnd( nLine );
+ Pair aPair = mpControlData->mpLayoutData->GetLineStartEnd( nLine );
if( aPair.A() <= nIndex && aPair.B() >= nIndex )
{
nRet = nIndex - aPair.A();
@@ -2173,10 +2167,10 @@ Rectangle TabControl::GetTabPageBounds( USHORT nPage ) const
{
Rectangle aRet;
- if( ! mpLayoutData || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
+ if( !HasLayoutData() || ! mpTabCtrlData->maLayoutPageIdToLine.size() )
FillLayoutData();
- if( mpLayoutData )
+ if( HasLayoutData() )
{
std::hash_map< int, int >::const_iterator it = mpTabCtrlData->maLayoutPageIdToLine.find( (int)nPage );
if( it != mpTabCtrlData->maLayoutPageIdToLine.end() )
diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx
index e5d83dc0733a..dd198ff521db 100644
--- a/vcl/source/fontsubset/cff.cxx
+++ b/vcl/source/fontsubset/cff.cxx
@@ -332,12 +332,13 @@ struct CffLocal
int mnLocalSubrBase;
int mnLocalSubrCount;
int mnLocalSubrBias;
- int mnNominalWidth;
- int mnDefaultWidth;
+
+ ValType maNominalWidth;
+ ValType maDefaultWidth;
// ATM hinting related values
- int mnStemStdHW;
- int mnStemStdVW;
+ ValType maStemStdHW;
+ ValType maStemStdVW;
ValVector maStemSnapH;
ValVector maStemSnapV;
ValVector maBlueValues;
@@ -461,10 +462,10 @@ public: // TODO: is public really needed?
void getHintPair( int nIndex, ValType* nMin, ValType* nEnd) const;
// accessing other charstring specifics
- bool hasCharWidth( void) const { return (mnCharWidth != -1);}
- int getCharWidth( void) const { return mnCharWidth;}
- void setNominalWidth( int nWidth) { mpCffLocal->mnNominalWidth = nWidth;}
- void setDefaultWidth( int nWidth) { mpCffLocal->mnDefaultWidth = nWidth;}
+ bool hasCharWidth( void) const { return (maCharWidth > 0);}
+ ValType getCharWidth( void) const { return maCharWidth;}
+ void setNominalWidth( ValType aWidth) { mpCffLocal->maNominalWidth = aWidth;}
+ void setDefaultWidth( ValType aWidth) { mpCffLocal->maDefaultWidth = aWidth;}
void updateWidth( bool bUseFirstVal);
private:
@@ -477,7 +478,7 @@ private:
int mnHorzHintSize;
ValType mnHintStack[ NMAXHINTS];
- int mnCharWidth;
+ ValType maCharWidth;
};
// --------------------------------------------------------------------
@@ -488,7 +489,7 @@ CffSubsetterContext::CffSubsetterContext( const U8* pBasePtr, int nBaseLen)
, mnStackIdx(0)
, mnHintSize(0)
, mnHorzHintSize(0)
-, mnCharWidth(-1)
+, maCharWidth(-1)
{
// setCharStringType( 1);
// TODO: new CffLocal[ mnFDAryCount];
@@ -542,13 +543,13 @@ inline void CffSubsetterContext::updateWidth( bool bUseFirstVal)
return;
#endif
if( bUseFirstVal) {
- mnCharWidth = static_cast<int>(mpCffLocal->mnNominalWidth + mnValStack[0]);
+ maCharWidth = mpCffLocal->maNominalWidth + mnValStack[0];
// remove bottom stack entry
--mnStackIdx;
for( int i = 0; i < mnStackIdx; ++i)
mnValStack[ i] = mnValStack[ i+1];
} else {
- mnCharWidth = mpCffLocal->mnDefaultWidth;
+ maCharWidth = mpCffLocal->maDefaultWidth;
}
}
@@ -615,7 +616,7 @@ void CffSubsetterContext::readCharString( const U8* pTypeOps, int nTypeLen)
mnStackIdx = 0;
mnHintSize = 0;
mnHorzHintSize = 0;
- mnCharWidth = -1;
+ maCharWidth = -1;
assert( nTypeLen >= 0);
// assert( nEnd <= getLength());
@@ -659,14 +660,14 @@ void CffSubsetterContext::readDictOp( void)
nVal = popVal();
nInt = static_cast<int>(nVal);
switch( nOpId) {
- case 10: mpCffLocal->mnStemStdHW = nInt; break; // "StdHW"
- case 11: mpCffLocal->mnStemStdVW = nInt; break; // "StdVW"
+ case 10: mpCffLocal->maStemStdHW = nVal; break; // "StdHW"
+ case 11: mpCffLocal->maStemStdVW = nVal; break; // "StdVW"
case 15: mnCharsetBase = nInt; break; // "charset"
case 16: mnEncodingBase = nInt; break; // "nEncoding"
case 17: mnCharStrBase = nInt; break; // "nCharStrings"
case 19: mpCffLocal->mnLocalSubrOffs = nInt; break;// "nSubrs"
- case 20: setDefaultWidth( nInt ); break; // "defaultWidthX"
- case 21: setNominalWidth( nInt ); break; // "nominalWidthX"
+ case 20: setDefaultWidth( nVal ); break; // "defaultWidthX"
+ case 21: setNominalWidth( nVal ); break; // "nominalWidthX"
case 909: mpCffLocal->mfBlueScale = nVal; break; // "BlueScale"
case 910: mpCffLocal->mfBlueShift = nVal; break; // "BlueShift"
case 911: mpCffLocal->mfBlueFuzz = nVal; break; // "BlueFuzz"
@@ -1477,7 +1478,7 @@ int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const
mbSawError = false;
mbNeedClose = false;
mbIgnoreHints = false;
-mnHintSize=mnHorzHintSize=mnStackIdx=0; mnCharWidth=-1;//#######
+mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//#######
mnCntrMask = 0;
while( mpReadPtr < mpReadEnd)
convertOneTypeOp();
@@ -1673,10 +1674,10 @@ CffLocal::CffLocal( void)
, mnLocalSubrBase( 0)
, mnLocalSubrCount( 0)
, mnLocalSubrBias( 0)
-, mnNominalWidth( 0)
-, mnDefaultWidth( 0)
-, mnStemStdHW( 0)
-, mnStemStdVW( 0)
+, maNominalWidth( 0)
+, maDefaultWidth( 0)
+, maStemStdHW( 0)
+, maStemStdVW( 0)
, mfBlueScale( 0.0)
, mfBlueShift( 0.0)
, mfBlueFuzz( 0.0)
@@ -2296,8 +2297,8 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
nPrivEntryCount += (mpCffLocal->mfBlueShift != 0.0);
nPrivEntryCount += (mpCffLocal->mfBlueFuzz != 0.0);
// emit stem hints only if non-default values
- nPrivEntryCount += (mpCffLocal->mnStemStdHW != 0);
- nPrivEntryCount += (mpCffLocal->mnStemStdVW != 0);
+ nPrivEntryCount += (mpCffLocal->maStemStdHW != 0);
+ nPrivEntryCount += (mpCffLocal->maStemStdVW != 0);
nPrivEntryCount += !mpCffLocal->maStemSnapH.empty();
nPrivEntryCount += !mpCffLocal->maStemSnapV.empty();
// emit other hints only if non-default values
@@ -2337,10 +2338,10 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
pOut += sprintf( pOut, "/BlueFuzz %.1f def\n", mpCffLocal->mfBlueFuzz);
// emit stem hint related privdict entries
- if( mpCffLocal->mnStemStdHW)
- pOut += sprintf( pOut, "/StdHW [%d] def\n", mpCffLocal->mnStemStdHW);
- if( mpCffLocal->mnStemStdVW)
- pOut += sprintf( pOut, "/StdVW [%d] def\n", mpCffLocal->mnStemStdVW);
+ if( mpCffLocal->maStemStdHW)
+ pOut += sprintf( pOut, "/StdHW [%g] def\n", mpCffLocal->maStemStdHW);
+ if( mpCffLocal->maStemStdVW)
+ pOut += sprintf( pOut, "/StdVW [%g] def\n", mpCffLocal->maStemStdVW);
rEmitter.emitValVector( "/StemSnapH [", "]ND\n", mpCffLocal->maStemSnapH);
rEmitter.emitValVector( "/StemSnapV [", "]ND\n", mpCffLocal->maStemSnapV);
@@ -2413,8 +2414,12 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
pOut += sprintf( pOut, " ND\n");
rEmitter.emitAllCrypted();
// provide individual glyphwidths if requested
- if( pGlyphWidths )
- pGlyphWidths[i] = getCharWidth();
+ if( pGlyphWidths ) {
+ ValType aCharWidth = getCharWidth();
+ if( maFontMatrix.size() >= 4)
+ aCharWidth *= 1000.0F * maFontMatrix[0];
+ pGlyphWidths[i] = static_cast<GlyphWidth>(aCharWidth);
+ }
}
pOut += sprintf( pOut, "end end\nreadonly put\nput\n");
pOut += sprintf( pOut, "dup/FontName get exch definefont pop\n");
@@ -2446,8 +2451,17 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
// provide details to the subset requesters, TODO: move into own method?
// note: Top and Bottom are flipped between Type1 and VCL
- rFSInfo.m_aFontBBox = Rectangle( Point( static_cast<long>(maFontBBox[0]), static_cast<long>(maFontBBox[1]) ),
- Point( static_cast<long>(maFontBBox[2]), static_cast<long>(maFontBBox[3]) ) );
+ // note: the rest of VCL expects the details below to be scaled like for an emUnits==1000 font
+ ValType fXFactor = 1.0;
+ ValType fYFactor = 1.0;
+ if( maFontMatrix.size() >= 4) {
+ fXFactor = 1000.0F * maFontMatrix[0];
+ fYFactor = 1000.0F * maFontMatrix[3];
+ }
+ rFSInfo.m_aFontBBox = Rectangle( Point( static_cast<long>(maFontBBox[0] * fXFactor),
+ static_cast<long>(maFontBBox[1] * fYFactor) ),
+ Point( static_cast<long>(maFontBBox[2] * fXFactor),
+ static_cast<long>(maFontBBox[3] * fYFactor) ) );
// PDF-Spec says the values below mean the ink bounds!
// TODO: use better approximations for these ink bounds
rFSInfo.m_nAscent = +rFSInfo.m_aFontBBox.Bottom(); // for capital letters
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index cfcac8851089..4e2ed20a7966 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -47,6 +47,7 @@
#include <tools/rc.h>
#endif
#include <vcl/svapp.hxx>
+#include <vcl/bmpacc.hxx>
// ------------
// - BitmapEx -
@@ -761,6 +762,78 @@ void BitmapEx::Draw( OutputDevice* pOutDev,
// ------------------------------------------------------------------
+sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
+{
+ sal_uInt8 nTransparency(0xff);
+
+ if(!aBitmap.IsEmpty())
+ {
+ if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height())
+ {
+ switch(eTransparent)
+ {
+ case TRANSPARENT_NONE:
+ {
+ // not transparent, ergo all covered
+ nTransparency = 0x00;
+ break;
+ }
+ case TRANSPARENT_COLOR:
+ {
+ Bitmap aTestBitmap(aBitmap);
+ BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
+
+ if(pRead)
+ {
+ const Color aColor = pRead->GetColor(nY, nX);
+
+ // if color is not equal to TransparentColor, we are not transparent
+ if(aColor != aTransparentColor)
+ {
+ nTransparency = 0x00;
+ }
+
+ aTestBitmap.ReleaseAccess(pRead);
+ }
+ break;
+ }
+ case TRANSPARENT_BITMAP:
+ {
+ if(!aMask.IsEmpty())
+ {
+ Bitmap aTestBitmap(aMask);
+ BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess();
+
+ if(pRead)
+ {
+ const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX));
+
+ if(bAlpha)
+ {
+ nTransparency = aBitmapColor.GetIndex();
+ }
+ else
+ {
+ if(0x00 != aBitmapColor.GetIndex())
+ {
+ nTransparency = 0x00;
+ }
+ }
+
+ aTestBitmap.ReleaseAccess(pRead);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return nTransparency;
+}
+
+// ------------------------------------------------------------------
+
SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx )
{
rBitmapEx.aBitmap.Write( rOStm );
diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk
index a09ae92dcb5e..c77508ea159e 100644
--- a/vcl/source/gdi/makefile.mk
+++ b/vcl/source/gdi/makefile.mk
@@ -51,7 +51,34 @@ CDEFS+=-DENABLE_GRAPHITE
# --- Files --------------------------------------------------------
-SLOFILES= $(SLO)$/salmisc.obj \
+EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
+ $(SLO)$/outdev.obj \
+ $(SLO)$/outdev3.obj \
+ $(SLO)$/gfxlink.obj \
+ $(SLO)$/print.obj \
+ $(SLO)$/print2.obj \
+ $(SLO)$/sallayout.obj \
+ $(SLO)$/image.obj \
+ $(SLO)$/impimage.obj \
+ $(SLO)$/impgraph.obj \
+ $(SLO)$/metric.obj \
+ $(SLO)$/pdfwriter_impl.obj \
+ $(SLO)$/pdffontcache.obj\
+ $(SLO)$/fontcfg.obj \
+ $(SLO)$/bmpconv.obj \
+ $(SLO)$/pdfextoutdevdata.obj \
+ $(SLO)$/fontcvt.obj \
+ $(SLO)$/jobset.obj \
+ $(SLO)$/impimagetree.obj \
+ $(SLO)$/pngread.obj \
+ $(SLO)$/pngwrite.obj \
+ $(SLO)$/virdev.obj \
+ $(SLO)$/impprn.obj \
+ $(SLO)$/gdimtf.obj \
+ $(SLO)$/graphictools.obj \
+ $(SLO)$/textlayout.obj
+
+SLOFILES= $(EXCEPTIONSFILES) \
$(SLO)$/animate.obj \
$(SLO)$/impanmvw.obj \
$(SLO)$/bitmap.obj \
@@ -68,81 +95,30 @@ SLOFILES= $(SLO)$/salmisc.obj \
$(SLO)$/cvtsvm.obj \
$(SLO)$/cvtgrf.obj \
$(SLO)$/font.obj \
- $(SLO)$/gdimtf.obj \
- $(SLO)$/gfxlink.obj \
$(SLO)$/gradient.obj \
$(SLO)$/hatch.obj \
$(SLO)$/graph.obj \
- $(SLO)$/image.obj \
- $(SLO)$/impimage.obj \
$(SLO)$/impbmp.obj \
- $(SLO)$/impgraph.obj \
- $(SLO)$/impimagetree.obj \
$(SLO)$/imagerepository.obj \
- $(SLO)$/impprn.obj \
$(SLO)$/impvect.obj \
$(SLO)$/implncvt.obj \
- $(SLO)$/jobset.obj \
$(SLO)$/lineinfo.obj \
$(SLO)$/mapmod.obj \
$(SLO)$/metaact.obj \
- $(SLO)$/metric.obj \
$(SLO)$/octree.obj \
$(SLO)$/outmap.obj \
- $(SLO)$/outdev.obj \
$(SLO)$/outdev2.obj \
- $(SLO)$/outdev3.obj \
$(SLO)$/outdev4.obj \
$(SLO)$/outdev5.obj \
$(SLO)$/outdev6.obj \
- $(SLO)$/virdev.obj \
- $(SLO)$/fontcvt.obj \
- $(SLO)$/print.obj \
- $(SLO)$/print2.obj \
$(SLO)$/regband.obj \
$(SLO)$/region.obj \
$(SLO)$/wall.obj \
- $(SLO)$/fontcfg.obj \
$(SLO)$/base14.obj \
$(SLO)$/pdfwriter.obj \
- $(SLO)$/pdfwriter_impl.obj \
- $(SLO)$/pdffontcache.obj\
- $(SLO)$/sallayout.obj \
$(SLO)$/salgdilayout.obj \
$(SLO)$/extoutdevdata.obj \
- $(SLO)$/pdfextoutdevdata.obj \
- $(SLO)$/salnativewidgets-none.obj \
- $(SLO)$/bmpconv.obj \
- $(SLO)$/pngread.obj \
- $(SLO)$/pngwrite.obj \
- $(SLO)$/graphictools.obj
-
-EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
- $(SLO)$/outdev.obj \
- $(SLO)$/outdev3.obj \
- $(SLO)$/gfxlink.obj \
- $(SLO)$/print.obj \
- $(SLO)$/print2.obj \
- $(SLO)$/sallayout.obj \
- $(SLO)$/image.obj \
- $(SLO)$/impimage.obj \
- $(SLO)$/impgraph.obj \
- $(SLO)$/metric.obj \
- $(SLO)$/pdfwriter_impl.obj \
- $(SLO)$/pdffontcache.obj\
- $(SLO)$/fontcfg.obj \
- $(SLO)$/bmpconv.obj \
- $(SLO)$/pdfextoutdevdata.obj \
- $(SLO)$/fontcvt.obj \
- $(SLO)$/jobset.obj \
- $(SLO)$/impimagetree.obj \
- $(SLO)$/pngread.obj \
- $(SLO)$/pngwrite.obj \
- $(SLO)$/virdev.obj \
- $(SLO)$/impprn.obj \
- $(SLO)$/gdimtf.obj \
- $(SLO)$/graphictools.obj
-
+ $(SLO)$/salnativewidgets-none.obj
# --- Targets ------------------------------------------------------
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index 8a057b3f3c7b..b6e0e1b8d441 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -61,6 +61,7 @@
#include <vcl/edit.hxx>
#include <vcl/fontcfg.hxx>
#include <vcl/sysdata.hxx>
+#include <vcl/textlayout.hxx>
#ifndef _OSL_FILE_H
#include <osl/file.h>
#endif
@@ -5257,7 +5258,7 @@ void OutputDevice::ImplDrawText( SalLayout& rSalLayout )
long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
long nWidth, const XubString& rStr,
- USHORT nStyle ) const
+ USHORT nStyle, const ::vcl::ITextLayout& _rLayout )
{
DBG_ASSERTWARNING( nWidth >= 0, "ImplGetTextLines: nWidth <= 0!" );
@@ -5295,7 +5296,7 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
while ( ( nBreakPos < nLen ) && ( rStr.GetChar( nBreakPos ) != _CR ) && ( rStr.GetChar( nBreakPos ) != _LF ) )
nBreakPos++;
- long nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ long nLineWidth = _rLayout.GetTextWidth( rStr, nPos, nBreakPos-nPos );
if ( ( nLineWidth > nWidth ) && ( nStyle & TEXT_DRAW_WORDBREAK ) )
{
if ( !xBI.is() )
@@ -5304,7 +5305,7 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
if ( xBI.is() )
{
const com::sun::star::lang::Locale& rDefLocale(Application::GetSettings().GetUILocale());
- xub_StrLen nSoftBreak = GetTextBreak( rStr, nWidth, nPos, nBreakPos - nPos );
+ xub_StrLen nSoftBreak = _rLayout.GetTextBreak( rStr, nWidth, nPos, nBreakPos - nPos );
DBG_ASSERT( nSoftBreak < nBreakPos, "Break?!" );
//aHyphOptions.hyphenIndex = nSoftBreak;
i18n::LineBreakResults aLBR = xBI->getLineBreak( aText, nSoftBreak, rDefLocale, nPos, aHyphOptions, aUserOptions );
@@ -5408,7 +5409,7 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
} // if ( xHyph.is() )
} // if ( (nStyle & TEXT_DRAW_WORDBREAK_HYPHENATION) == TEXT_DRAW_WORDBREAK_HYPHENATION )
}
- nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ nLineWidth = _rLayout.GetTextWidth( rStr, nPos, nBreakPos-nPos );
}
else
{
@@ -5422,14 +5423,14 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
{
if( nSpacePos > nPos )
nSpacePos--;
- nW = GetTextWidth( rStr, nPos, nSpacePos-nPos );
+ nW = _rLayout.GetTextWidth( rStr, nPos, nSpacePos-nPos );
}
} while( nW > nWidth );
if( nSpacePos != STRING_NOTFOUND )
{
nBreakPos = nSpacePos;
- nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
+ nLineWidth = _rLayout.GetTextWidth( rStr, nPos, nBreakPos-nPos );
if( nBreakPos < rStr.Len()-1 )
nBreakPos++;
}
@@ -6159,6 +6160,10 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const String& rStr,
if ( !IsDeviceOutputNecessary() )
return;
+ if( mbInitClipRegion )
+ ImplInitClipRegion();
+ if( mbOutputClipped )
+ return;
SalLayout* pSalLayout = ImplLayout( rStr, nIndex, nLen, rStartPt, 0, pDXAry, true );
if( pSalLayout )
@@ -6771,9 +6776,10 @@ xub_StrLen OutputDevice::GetTextBreak( const String& rStr, long nTextWidth,
// -----------------------------------------------------------------------
-void OutputDevice::ImplDrawText( const Rectangle& rRect,
+void OutputDevice::ImplDrawText( OutputDevice& rTargetDevice, const Rectangle& rRect,
const String& rOrigStr, USHORT nStyle,
- MetricVector* pVector, String* pDisplayText )
+ MetricVector* pVector, String* pDisplayText,
+ ::vcl::ITextLayout& _rLayout )
{
Color aOldTextColor;
Color aOldTextFillColor;
@@ -6782,12 +6788,12 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
{
BOOL bHighContrastBlack = FALSE;
BOOL bHighContrastWhite = FALSE;
- const StyleSettings& rStyleSettings( GetSettings().GetStyleSettings() );
+ const StyleSettings& rStyleSettings( rTargetDevice.GetSettings().GetStyleSettings() );
if( rStyleSettings.GetHighContrastMode() )
{
Color aCol;
- if( IsBackground() )
- aCol = GetBackground().GetColor();
+ if( rTargetDevice.IsBackground() )
+ aCol = rTargetDevice.GetBackground().GetColor();
else
// best guess is the face color here
// but it may be totally wrong. the background color
@@ -6798,16 +6804,16 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
bHighContrastWhite = aCol.IsBright();
}
- aOldTextColor = GetTextColor();
- if ( IsTextFillColor() )
+ aOldTextColor = rTargetDevice.GetTextColor();
+ if ( rTargetDevice.IsTextFillColor() )
{
bRestoreFillColor = TRUE;
- aOldTextFillColor = GetTextFillColor();
+ aOldTextFillColor = rTargetDevice.GetTextFillColor();
}
if( bHighContrastBlack )
- SetTextColor( COL_GREEN );
+ rTargetDevice.SetTextColor( COL_GREEN );
else if( bHighContrastWhite )
- SetTextColor( COL_LIGHTGREEN );
+ rTargetDevice.SetTextColor( COL_LIGHTGREEN );
else
{
// draw disabled text always without shadow
@@ -6818,7 +6824,7 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
aRect.Move( 1, 1 );
DrawText( aRect, rOrigStr, nStyle & ~TEXT_DRAW_DISABLE );
*/
- SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
+ rTargetDevice.SetTextColor( rTargetDevice.GetSettings().GetStyleSettings().GetDisableColor() );
}
}
@@ -6830,14 +6836,16 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
Point aPos = rRect.TopLeft();
- long nTextHeight = GetTextHeight();
- TextAlign eAlign = GetTextAlign();
+ long nTextHeight = rTargetDevice.GetTextHeight();
+ TextAlign eAlign = rTargetDevice.GetTextAlign();
xub_StrLen nMnemonicPos = STRING_NOTFOUND;
String aStr = rOrigStr;
if ( nStyle & TEXT_DRAW_MNEMONIC )
aStr = GetNonMnemonicString( aStr, nMnemonicPos );
+ const bool bDrawMnemonics = !(rTargetDevice.GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) && !pVector;
+
// Mehrzeiligen Text behandeln wir anders
if ( nStyle & TEXT_DRAW_MULTILINE )
{
@@ -6852,7 +6860,7 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
if ( nTextHeight )
{
- nMaxTextWidth = ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle );
+ nMaxTextWidth = ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle, _rLayout );
nLines = (xub_StrLen)(nHeight/nTextHeight);
nFormatLines = aMultiLineInfo.Count();
if ( !nLines )
@@ -6874,7 +6882,7 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
if ( aLastLine.GetChar( i ) == _LF )
aLastLine.SetChar( i, ' ' );
}
- aLastLine = GetEllipsisString( aLastLine, nWidth, nStyle );
+ aLastLine = ImplGetEllipsisString( rTargetDevice, aLastLine, nWidth, nStyle, _rLayout );
nStyle &= ~(TEXT_DRAW_VCENTER | TEXT_DRAW_BOTTOM);
nStyle |= TEXT_DRAW_TOP;
}
@@ -6892,8 +6900,8 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
// Clipping setzen
if ( nStyle & TEXT_DRAW_CLIP )
{
- Push( PUSH_CLIPREGION );
- IntersectClipRegion( rRect );
+ rTargetDevice.Push( PUSH_CLIPREGION );
+ rTargetDevice.IntersectClipRegion( rRect );
}
// Vertikales Alignment
@@ -6906,7 +6914,7 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
if ( eAlign == ALIGN_BOTTOM )
aPos.Y() += nTextHeight;
else if ( eAlign == ALIGN_BASELINE )
- aPos.Y() += GetFontMetric().GetAscent();
+ aPos.Y() += rTargetDevice.GetFontMetric().GetAscent();
// Alle Zeilen ausgeben, bis auf die letzte
for ( i = 0; i < nFormatLines; i++ )
@@ -6918,8 +6926,8 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
aPos.X() += (nWidth-pLineInfo->GetWidth())/2;
xub_StrLen nIndex = pLineInfo->GetIndex();
xub_StrLen nLineLen = pLineInfo->GetLen();
- DrawText( aPos, aStr, nIndex, nLineLen, pVector, pDisplayText );
- if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) && !pVector )
+ _rLayout.DrawText( aPos, aStr, nIndex, nLineLen, pVector, pDisplayText );
+ if ( bDrawMnemonics )
{
if ( (nMnemonicPos >= nIndex) && (nMnemonicPos < nIndex+nLineLen) )
{
@@ -6928,16 +6936,16 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
long nMnemonicWidth;
sal_Int32* pCaretXArray = (sal_Int32*) alloca( 2 * sizeof(sal_Int32) * nLineLen );
- /*BOOL bRet =*/ GetCaretPositions( aStr, pCaretXArray,
- nIndex, nLineLen);
+ /*BOOL bRet =*/ _rLayout.GetCaretPositions( aStr, pCaretXArray,
+ nIndex, nLineLen );
long lc_x1 = pCaretXArray[2*(nMnemonicPos - nIndex)];
long lc_x2 = pCaretXArray[2*(nMnemonicPos - nIndex)+1];
- nMnemonicWidth = ::abs((int)(lc_x1 - lc_x2));
+ nMnemonicWidth = rTargetDevice.ImplLogicWidthToDevicePixel( ::abs((int)(lc_x1 - lc_x2)) );
- Point aTempPos = LogicToPixel( aPos );
- nMnemonicX = mnOutOffX + aTempPos.X() + ImplLogicWidthToDevicePixel( Min( lc_x1, lc_x2 ) );
- nMnemonicY = mnOutOffY + aTempPos.Y() + ImplLogicWidthToDevicePixel( GetFontMetric().GetAscent() );
- ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
+ Point aTempPos = rTargetDevice.LogicToPixel( aPos );
+ nMnemonicX = rTargetDevice.GetOutOffXPixel() + aTempPos.X() + rTargetDevice.ImplLogicWidthToDevicePixel( Min( lc_x1, lc_x2 ) );
+ nMnemonicY = rTargetDevice.GetOutOffYPixel() + aTempPos.Y() + rTargetDevice.ImplLogicWidthToDevicePixel( rTargetDevice.GetFontMetric().GetAscent() );
+ rTargetDevice.ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
}
}
aPos.Y() += nTextHeight;
@@ -6948,26 +6956,26 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
// Gibt es noch eine letzte Zeile, dann diese linksbuendig ausgeben,
// da die Zeile gekuerzt wurde
if ( aLastLine.Len() )
- DrawText( aPos, aLastLine, 0, STRING_LEN, pVector, pDisplayText );
+ _rLayout.DrawText( aPos, aLastLine, 0, STRING_LEN, pVector, pDisplayText );
// Clipping zuruecksetzen
if ( nStyle & TEXT_DRAW_CLIP )
- Pop();
+ rTargetDevice.Pop();
}
}
else
{
- long nTextWidth = GetTextWidth( aStr );
+ long nTextWidth = _rLayout.GetTextWidth( aStr, 0, STRING_LEN );
// Evt. Text kuerzen
if ( nTextWidth > nWidth )
{
if ( nStyle & TEXT_DRAW_ELLIPSIS )
{
- aStr = GetEllipsisString( aStr, nWidth, nStyle );
+ aStr = ImplGetEllipsisString( rTargetDevice, aStr, nWidth, nStyle, _rLayout );
nStyle &= ~(TEXT_DRAW_CENTER | TEXT_DRAW_RIGHT);
nStyle |= TEXT_DRAW_LEFT;
- nTextWidth = GetTextWidth( aStr );
+ nTextWidth = _rLayout.GetTextWidth( aStr, 0, aStr.Len() );
}
}
else
@@ -6986,7 +6994,7 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
if ( eAlign == ALIGN_BOTTOM )
aPos.Y() += nTextHeight;
else if ( eAlign == ALIGN_BASELINE )
- aPos.Y() += GetFontMetric().GetAscent();
+ aPos.Y() += rTargetDevice.GetFontMetric().GetAscent();
if ( nStyle & TEXT_DRAW_BOTTOM )
aPos.Y() += nHeight-nTextHeight;
@@ -6999,44 +7007,44 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
if ( nMnemonicPos != STRING_NOTFOUND )
{
sal_Int32* pCaretXArray = (sal_Int32*) alloca( 2 * sizeof(sal_Int32) * aStr.Len() );
- /*BOOL bRet =*/ GetCaretPositions( aStr, pCaretXArray, 0, aStr.Len() );
+ /*BOOL bRet =*/ _rLayout.GetCaretPositions( aStr, pCaretXArray, 0, aStr.Len() );
long lc_x1 = pCaretXArray[2*(nMnemonicPos)];
long lc_x2 = pCaretXArray[2*(nMnemonicPos)+1];
- nMnemonicWidth = ::abs((int)(lc_x1 - lc_x2));
+ nMnemonicWidth = rTargetDevice.ImplLogicWidthToDevicePixel( ::abs((int)(lc_x1 - lc_x2)) );
- Point aTempPos = LogicToPixel( aPos );
- nMnemonicX = mnOutOffX + aTempPos.X() + ImplLogicWidthToDevicePixel( Min(lc_x1, lc_x2) );
- nMnemonicY = mnOutOffY + aTempPos.Y() + ImplLogicWidthToDevicePixel( GetFontMetric().GetAscent() );
+ Point aTempPos = rTargetDevice.LogicToPixel( aPos );
+ nMnemonicX = rTargetDevice.GetOutOffXPixel() + aTempPos.X() + rTargetDevice.ImplLogicWidthToDevicePixel( Min(lc_x1, lc_x2) );
+ nMnemonicY = rTargetDevice.GetOutOffYPixel() + aTempPos.Y() + rTargetDevice.ImplLogicWidthToDevicePixel( rTargetDevice.GetFontMetric().GetAscent() );
}
if ( nStyle & TEXT_DRAW_CLIP )
{
- Push( PUSH_CLIPREGION );
- IntersectClipRegion( rRect );
- DrawText( aPos, aStr, 0, STRING_LEN, pVector, pDisplayText );
- if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) && !pVector )
+ rTargetDevice.Push( PUSH_CLIPREGION );
+ rTargetDevice.IntersectClipRegion( rRect );
+ _rLayout.DrawText( aPos, aStr, 0, STRING_LEN, pVector, pDisplayText );
+ if ( bDrawMnemonics )
{
if ( nMnemonicPos != STRING_NOTFOUND )
- ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
+ rTargetDevice.ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
}
- Pop();
+ rTargetDevice.Pop();
}
else
{
- DrawText( aPos, aStr, 0, STRING_LEN, pVector, pDisplayText );
- if ( !(GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_NOMNEMONICS) && !pVector )
+ _rLayout.DrawText( aPos, aStr, 0, STRING_LEN, pVector, pDisplayText );
+ if ( bDrawMnemonics )
{
if ( nMnemonicPos != STRING_NOTFOUND )
- ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
+ rTargetDevice.ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
}
}
}
if ( nStyle & TEXT_DRAW_DISABLE && !pVector )
{
- SetTextColor( aOldTextColor );
+ rTargetDevice.SetTextColor( aOldTextColor );
if ( bRestoreFillColor )
- SetTextFillColor( aOldTextFillColor );
+ rTargetDevice.SetTextFillColor( aOldTextFillColor );
}
}
@@ -7069,7 +7077,8 @@ void OutputDevice::AddTextRectActions( const Rectangle& rRect,
// #i47157# Factored out to ImplDrawTextRect(), to be shared
// between us and DrawText()
- ImplDrawText( rRect, rOrigStr, nStyle, NULL, NULL );
+ DefaultTextLayout aLayout( *this );
+ ImplDrawText( *this, rRect, rOrigStr, nStyle, NULL, NULL, aLayout );
// and restore again
EnableOutput( bOutputEnabled );
@@ -7078,10 +7087,9 @@ void OutputDevice::AddTextRectActions( const Rectangle& rRect,
// -----------------------------------------------------------------------
-void OutputDevice::DrawText( const Rectangle& rRect,
- const String& rOrigStr, USHORT nStyle,
- MetricVector* pVector, String* pDisplayText )
-
+void OutputDevice::DrawText( const Rectangle& rRect, const String& rOrigStr, USHORT nStyle,
+ MetricVector* pVector, String* pDisplayText,
+ ::vcl::ITextLayout* _pTextLayout )
{
if( mpOutDevData && mpOutDevData->mpRecordLayout )
{
@@ -7092,10 +7100,11 @@ void OutputDevice::DrawText( const Rectangle& rRect,
DBG_TRACE( "OutputDevice::DrawText( const Rectangle& )" );
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
- if ( mpMetaFile )
+ bool bDecomposeTextRectAction = ( _pTextLayout != NULL ) && _pTextLayout->DecomposeTextRectAction();
+ if ( mpMetaFile && !bDecomposeTextRectAction )
mpMetaFile->AddAction( new MetaTextRectAction( rRect, rOrigStr, nStyle ) );
- if ( ( !IsDeviceOutputNecessary() && ! pVector ) || !rOrigStr.Len() || rRect.IsEmpty() )
+ if ( ( !IsDeviceOutputNecessary() && !pVector && !bDecomposeTextRectAction ) || !rOrigStr.Len() || rRect.IsEmpty() )
return;
// we need a graphics
@@ -7103,17 +7112,19 @@ void OutputDevice::DrawText( const Rectangle& rRect,
return;
if( mbInitClipRegion )
ImplInitClipRegion();
- if( mbOutputClipped )
+ if( mbOutputClipped && !bDecomposeTextRectAction )
return;
// temporarily disable mtf action generation (ImplDrawText _does_
// create META_TEXT_ACTIONs otherwise)
GDIMetaFile* pMtf = mpMetaFile;
- mpMetaFile = NULL;
+ if ( !bDecomposeTextRectAction )
+ mpMetaFile = NULL;
- // #i47157# Factored out to ImplDrawTextRect(), to be used also
+ // #i47157# Factored out to ImplDrawText(), to be used also
// from AddTextRectActions()
- ImplDrawText( rRect, rOrigStr, nStyle, pVector, pDisplayText );
+ DefaultTextLayout aDefaultLayout( *this );
+ ImplDrawText( *this, rRect, rOrigStr, nStyle, pVector, pDisplayText, _pTextLayout ? *_pTextLayout : aDefaultLayout );
// and enable again
mpMetaFile = pMtf;
@@ -7125,8 +7136,9 @@ void OutputDevice::DrawText( const Rectangle& rRect,
// -----------------------------------------------------------------------
Rectangle OutputDevice::GetTextRect( const Rectangle& rRect,
- const String& rOrigStr, USHORT nStyle,
- TextRectInfo* pInfo ) const
+ const XubString& rStr, USHORT nStyle,
+ TextRectInfo* pInfo,
+ const ::vcl::ITextLayout* _pTextLayout ) const
{
DBG_TRACE( "OutputDevice::GetTextRect()" );
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
@@ -7137,7 +7149,7 @@ Rectangle OutputDevice::GetTextRect( const Rectangle& rRect,
long nMaxWidth;
long nTextHeight = GetTextHeight();
- String aStr = rOrigStr;
+ String aStr = rStr;
if ( nStyle & TEXT_DRAW_MNEMONIC )
aStr = GetNonMnemonicString( aStr );
@@ -7149,7 +7161,8 @@ Rectangle OutputDevice::GetTextRect( const Rectangle& rRect,
xub_StrLen i;
nMaxWidth = 0;
- ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle );
+ DefaultTextLayout aDefaultLayout( *const_cast< OutputDevice* >( this ) );
+ ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle, _pTextLayout ? *_pTextLayout : aDefaultLayout );
nFormatLines = aMultiLineInfo.Count();
if ( !nTextHeight )
nTextHeight = 1;
@@ -7197,7 +7210,7 @@ Rectangle OutputDevice::GetTextRect( const Rectangle& rRect,
else
{
nLines = 1;
- nMaxWidth = GetTextWidth( aStr );
+ nMaxWidth = _pTextLayout ? _pTextLayout->GetTextWidth( aStr, 0, aStr.Len() ) : GetTextWidth( aStr );
if ( pInfo )
{
@@ -7256,11 +7269,20 @@ static BOOL ImplIsCharIn( xub_Unicode c, const sal_Char* pStr )
String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
USHORT nStyle ) const
{
- DBG_TRACE( "OutputDevice::GetEllipsisString()" );
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+ DefaultTextLayout aTextLayout( *const_cast< OutputDevice* >( this ) );
+ return ImplGetEllipsisString( *this, rOrigStr, nMaxWidth, nStyle, aTextLayout );
+}
+
+// -----------------------------------------------------------------------
+
+String OutputDevice::ImplGetEllipsisString( const OutputDevice& rTargetDevice, const XubString& rOrigStr, long nMaxWidth,
+ USHORT nStyle, const ::vcl::ITextLayout& _rLayout )
+{
+ DBG_TRACE( "OutputDevice::ImplGetEllipsisString()" );
String aStr = rOrigStr;
- xub_StrLen nIndex = GetTextBreak( aStr, nMaxWidth );
+ xub_StrLen nIndex = _rLayout.GetTextBreak( aStr, nMaxWidth, 0, aStr.Len() );
if ( nIndex != STRING_LEN )
@@ -7271,7 +7293,7 @@ String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
if ( nIndex > 1 )
{
aStr.AppendAscii( "..." );
- while ( aStr.Len() && (GetTextWidth( aStr ) > nMaxWidth) )
+ while ( aStr.Len() && (_rLayout.GetTextWidth( aStr, 0, aStr.Len() ) > nMaxWidth) )
{
if ( (nIndex > 1) || (nIndex == aStr.Len()) )
nIndex--;
@@ -7307,8 +7329,8 @@ String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
XubString aLastStr( aStr, nLastContent, aStr.Len() );
XubString aTempLastStr1( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
aTempLastStr1 += aLastStr;
- if ( GetTextWidth( aTempLastStr1 ) > nMaxWidth )
- aStr = GetEllipsisString( aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ if ( _rLayout.GetTextWidth( aTempLastStr1, 0, aTempLastStr1.Len() ) > nMaxWidth )
+ aStr = OutputDevice::ImplGetEllipsisString( rTargetDevice, aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS, _rLayout );
else
{
USHORT nFirstContent = 0;
@@ -7323,7 +7345,7 @@ String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
nFirstContent++;
if ( nFirstContent >= nLastContent )
- aStr = GetEllipsisString( aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ aStr = OutputDevice::ImplGetEllipsisString( rTargetDevice, aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS, _rLayout );
else
{
if ( nFirstContent > 4 )
@@ -7332,8 +7354,8 @@ String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
aFirstStr.AppendAscii( "..." );
XubString aTempStr = aFirstStr;
aTempStr += aLastStr;
- if ( GetTextWidth( aTempStr ) > nMaxWidth )
- aStr = GetEllipsisString( aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS );
+ if ( _rLayout.GetTextWidth( aTempStr, 0, aTempStr.Len() ) > nMaxWidth )
+ aStr = OutputDevice::ImplGetEllipsisString( rTargetDevice, aStr, nMaxWidth, nStyle | TEXT_DRAW_ENDELLIPSIS, _rLayout );
else
{
do
@@ -7357,7 +7379,7 @@ String OutputDevice::GetEllipsisString( const String& rOrigStr, long nMaxWidth,
XubString aTempLastStr( aStr, nLastContent, aStr.Len() );
aTempStr = aFirstStr;
aTempStr += aTempLastStr;
- if ( GetTextWidth( aTempStr ) > nMaxWidth )
+ if ( _rLayout.GetTextWidth( aTempStr, 0, aTempStr.Len() ) > nMaxWidth )
break;
}
}
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index dc3ead5d2d6f..d4fc6fa27117 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -41,7 +41,6 @@
#include <tools/debug.hxx>
#include <tools/zcodec.hxx>
#include <tools/stream.hxx>
-#include <tools/urlobj.hxx> //for relative url
#include <i18npool/mslangid.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bmpacc.hxx>
@@ -51,6 +50,7 @@
#include <vcl/sallayout.hxx>
#include <vcl/metric.hxx>
#include <vcl/fontsubset.hxx>
+#include <vcl/textlayout.hxx>
#include <svsys.h>
#include <vcl/salgdi.hxx>
#include <vcl/svapp.hxx>
@@ -7310,7 +7310,8 @@ void PDFWriterImpl::drawText( const Rectangle& rRect, const String& rOrigStr, US
if ( nTextHeight )
{
- nMaxTextWidth = m_pReferenceDevice->ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle );
+ ::vcl::DefaultTextLayout aLayout( *m_pReferenceDevice );
+ nMaxTextWidth = OutputDevice::ImplGetTextLines( aMultiLineInfo, nWidth, aStr, nStyle, aLayout );
nLines = (xub_StrLen)(nHeight/nTextHeight);
nFormatLines = aMultiLineInfo.Count();
if ( !nLines )
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 21ac05a498fc..1f44b823ce44 100755
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -95,11 +95,12 @@ bool IsDiacritic( sal_UCS4 nChar )
if( nChar >= 0x2100 )
return false;
+ // TODO: #i105058# use icu uchar.h's character classification instead of the handcrafted table
struct DiaRange { sal_UCS4 mnMin, mnEnd;};
static const DiaRange aRanges[] = {
{0x0300, 0x0370},
- {0x0590, 0x05C0}, {0x05C1, 0x05C3}, {0x05C3, 0x05C6}, {0x05C7, 0x05C8},
- {0x0610, 0x061B}, {0x064B, 0x0660}, {0x0670, 0x0671}, {0x06D6, 0x06DC}, {0x06DF, 0x06EE},
+ {0x0590, 0x05BE}, {0x05BF, 0x05C0}, {0x05C1, 0x05C3}, {0x05C4, 0x05C6}, {0x05C7, 0x05C8},
+ {0x0610, 0x061B}, {0x064B, 0x0660}, {0x0670, 0x0671}, {0x06D6, 0x06DD}, {0x06DF, 0x06E5}, {0x06E7, 0x06E9}, {0x06EA,0x06EF},
{0x0730, 0x074D}, {0x07A6, 0x07B1}, {0x07EB, 0x07F4},
#if 0 // all known fonts have zero-width diacritics already, so no need to query it
{0x0900, 0x0904}, {0x093C, 0x093D}, {0x0941, 0x0948}, {0x094D, 0x0950}, {0x0951, 0x0958},
@@ -107,7 +108,8 @@ bool IsDiacritic( sal_UCS4 nChar )
{0x0A00, 0x0A05}, {0x0A3C, 0x0A59}, //...
#endif
{0x1DC0, 0x1E00},
- {0x205F, 0x2070}, {0x20D0, 0x2100}
+ {0x205F, 0x2070}, {0x20D0, 0x2100},
+ {0xFB1E, 0xFB1F}
};
// TODO: almost anything is faster than an O(n) search
diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx
new file mode 100755
index 000000000000..67a30c351b7a
--- /dev/null
+++ b/vcl/source/gdi/textlayout.cxx
@@ -0,0 +1,384 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2009 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include "vcl/ctrl.hxx"
+#include "vcl/outdev.hxx"
+#include "vcl/outfont.hxx"
+#include "vcl/textlayout.hxx"
+
+#include <com/sun/star/i18n/ScriptDirection.hpp>
+
+#include <tools/diagnose_ex.h>
+
+#if OSL_DEBUG_LEVEL > 1
+#include <rtl/strbuf.hxx>
+#endif
+
+//........................................................................
+namespace vcl
+{
+//........................................................................
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::Exception;
+ namespace ScriptDirection = ::com::sun::star::i18n::ScriptDirection;
+
+ //====================================================================
+ //= DefaultTextLayout
+ //====================================================================
+ //--------------------------------------------------------------------
+ DefaultTextLayout::~DefaultTextLayout()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ long DefaultTextLayout::GetTextWidth( const XubString& _rText, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ return m_rTargetDevice.GetTextWidth( _rText, _nStartIndex, _nLength );
+ }
+
+ //--------------------------------------------------------------------
+ void DefaultTextLayout::DrawText( const Point& _rStartPoint, const XubString& _rText, xub_StrLen _nStartIndex,
+ xub_StrLen _nLength, MetricVector* _pVector, String* _pDisplayText )
+ {
+ m_rTargetDevice.DrawText( _rStartPoint, _rText, _nStartIndex, _nLength, _pVector, _pDisplayText );
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultTextLayout::GetCaretPositions( const XubString& _rText, sal_Int32* _pCaretXArray,
+ xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ return m_rTargetDevice.GetCaretPositions( _rText, _pCaretXArray, _nStartIndex, _nLength );
+ }
+
+ //--------------------------------------------------------------------
+ xub_StrLen DefaultTextLayout::GetTextBreak( const XubString& _rText, long _nMaxTextWidth, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ return m_rTargetDevice.GetTextBreak( _rText, _nMaxTextWidth, _nStartIndex, _nLength );
+ }
+
+ //--------------------------------------------------------------------
+ bool DefaultTextLayout::DecomposeTextRectAction() const
+ {
+ return false;
+ }
+
+ //====================================================================
+ //= ReferenceDeviceTextLayout
+ //====================================================================
+ class ReferenceDeviceTextLayout : public ITextLayout
+ {
+ public:
+ ReferenceDeviceTextLayout( const Control& _rControl, OutputDevice& _rTargetDevice, OutputDevice& _rReferenceDevice );
+ virtual ~ReferenceDeviceTextLayout();
+
+ // ITextLayout
+ virtual long GetTextWidth( const XubString& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const;
+ virtual void DrawText( const Point& _rStartPoint, const XubString& _rText, xub_StrLen _nStartIndex, xub_StrLen _nLength, MetricVector* _pVector, String* _pDisplayText );
+ virtual bool GetCaretPositions( const XubString& _rText, sal_Int32* _pCaretXArray, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const;
+ virtual xub_StrLen GetTextBreak( const XubString& _rText, long _nMaxTextWidth, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const;
+ virtual bool DecomposeTextRectAction() const;
+
+ public:
+ // equivalents to the respective OutputDevice methods, which take the reference device into account
+ long GetTextArray( const XubString& _rText, sal_Int32* _pDXAry, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const;
+ Rectangle DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText );
+
+ protected:
+ void onBeginDrawText()
+ {
+ m_aCompleteTextRect.SetEmpty();
+ }
+ Rectangle onEndDrawText()
+ {
+ return m_aCompleteTextRect;
+ }
+
+ private:
+ OutputDevice& m_rTargetDevice;
+ OutputDevice& m_rReferenceDevice;
+ Font m_aUnzoomedPointFont;
+ const Fraction m_aZoom;
+ const bool m_bRTLEnabled;
+
+ Rectangle m_aCompleteTextRect;
+ };
+
+ //====================================================================
+ //= ControlTextRenderer
+ //====================================================================
+ ReferenceDeviceTextLayout::ReferenceDeviceTextLayout( const Control& _rControl, OutputDevice& _rTargetDevice,
+ OutputDevice& _rReferenceDevice )
+ :m_rTargetDevice( _rTargetDevice )
+ ,m_rReferenceDevice( _rReferenceDevice )
+ ,m_aUnzoomedPointFont( _rControl.GetUnzoomedControlPointFont() )
+ ,m_aZoom( _rControl.GetZoom() )
+ ,m_bRTLEnabled( _rControl.IsRTLEnabled() )
+ {
+ m_rTargetDevice.Push( PUSH_MAPMODE | PUSH_FONT | PUSH_TEXTLAYOUTMODE );
+
+ MapMode aTargetMapMode( m_rTargetDevice.GetMapMode() );
+ OSL_ENSURE( aTargetMapMode.GetOrigin() == Point(), "ReferenceDeviceTextLayout::ReferenceDeviceTextLayout: uhm, the code below won't work here ..." );
+
+ // normally, controls simulate "zoom" by "zooming" the font. This is responsible for (part of) the discrepancies
+ // between text in Writer and text in controls in Writer, though both have the same font.
+ // So, if we have a zoom set at the control, then we do not scale the font, but instead modify the map mode
+ // to accomodate for the zoom.
+ aTargetMapMode.SetScaleX( m_aZoom ); // TODO: shouldn't this be "current_scale * zoom"?
+ aTargetMapMode.SetScaleY( m_aZoom );
+
+ // also, use a higher-resolution map unit than "pixels", which should save us some rounding errors when
+ // translating coordinates between the reference device and the target device.
+ OSL_ENSURE( aTargetMapMode.GetMapUnit() == MAP_PIXEL,
+ "ReferenceDeviceTextLayout::ReferenceDeviceTextLayout: this class is not expected to work with such target devices!" );
+ // we *could* adjust all the code in this class to handle this case, but at the moment, it's not necessary
+ const MapUnit eTargetMapUnit = m_rReferenceDevice.GetMapMode().GetMapUnit();
+ aTargetMapMode.SetMapUnit( eTargetMapUnit );
+ OSL_ENSURE( aTargetMapMode.GetMapUnit() != MAP_PIXEL,
+ "ReferenceDeviceTextLayout::ReferenceDeviceTextLayout: a reference device which has map mode PIXEL?!" );
+
+ m_rTargetDevice.SetMapMode( aTargetMapMode );
+
+ // now that the Zoom is part of the map mode, reset the target device's font to the "unzoomed" version
+ Font aDrawFont( m_aUnzoomedPointFont );
+ aDrawFont.SetSize( m_rTargetDevice.LogicToLogic( aDrawFont.GetSize(), MAP_POINT, eTargetMapUnit ) );
+ _rTargetDevice.SetFont( aDrawFont );
+
+ // transfer font to the reference device
+ m_rReferenceDevice.Push( PUSH_FONT | PUSH_TEXTLAYOUTMODE );
+ Font aRefFont( m_aUnzoomedPointFont );
+ aRefFont.SetSize( OutputDevice::LogicToLogic(
+ aRefFont.GetSize(), MAP_POINT, m_rReferenceDevice.GetMapMode().GetMapUnit() ) );
+ m_rReferenceDevice.SetFont( aRefFont );
+ }
+
+ //--------------------------------------------------------------------
+ ReferenceDeviceTextLayout::~ReferenceDeviceTextLayout()
+ {
+ m_rReferenceDevice.Pop();
+ m_rTargetDevice.Pop();
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //................................................................
+ bool lcl_normalizeLength( const XubString& _rText, const xub_StrLen _nStartIndex, xub_StrLen& _io_nLength )
+ {
+ xub_StrLen nTextLength = _rText.Len();
+ if ( _nStartIndex > nTextLength )
+ return false;
+ if ( _nStartIndex + _io_nLength > nTextLength )
+ _io_nLength = nTextLength - _nStartIndex;
+ return true;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ long ReferenceDeviceTextLayout::GetTextArray( const XubString& _rText, sal_Int32* _pDXAry, xub_StrLen _nStartIndex,
+ xub_StrLen _nLength ) const
+ {
+ if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) )
+ return 0;
+
+ // retrieve the character widths from the reference device
+ long nTextWidth = m_rReferenceDevice.GetTextArray( _rText, _pDXAry, _nStartIndex, _nLength );
+#if OSL_DEBUG_LEVEL > 1
+ if ( _pDXAry )
+ {
+ ::rtl::OStringBuffer aTrace;
+ aTrace.append( "ReferenceDeviceTextLayout::GetTextArray( " );
+ aTrace.append( ::rtl::OUStringToOString( _rText, RTL_TEXTENCODING_UTF8 ) );
+ aTrace.append( " ): " );
+ aTrace.append( nTextWidth );
+ aTrace.append( " = ( " );
+ for ( size_t i=0; i<_nLength; )
+ {
+ aTrace.append( _pDXAry[i] );
+ if ( ++i < _nLength )
+ aTrace.append( ", " );
+ }
+ aTrace.append( ")" );
+ OSL_TRACE( aTrace.makeStringAndClear().getStr() );
+ }
+#endif
+ return nTextWidth;
+ }
+
+ //--------------------------------------------------------------------
+ long ReferenceDeviceTextLayout::GetTextWidth( const XubString& _rText, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ return GetTextArray( _rText, NULL, _nStartIndex, _nLength );
+ }
+
+ //--------------------------------------------------------------------
+ void ReferenceDeviceTextLayout::DrawText( const Point& _rStartPoint, const XubString& _rText, xub_StrLen _nStartIndex, xub_StrLen _nLength, MetricVector* _pVector, String* _pDisplayText )
+ {
+ if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) )
+ return;
+
+ if ( _pVector && _pDisplayText )
+ {
+ MetricVector aGlyphBounds;
+ m_rReferenceDevice.GetGlyphBoundRects( _rStartPoint, _rText, _nStartIndex, _nLength, _nStartIndex, aGlyphBounds );
+ ::std::copy(
+ aGlyphBounds.begin(), aGlyphBounds.end(),
+ ::std::insert_iterator< MetricVector > ( *_pVector, _pVector->end() ) );
+ _pDisplayText->Append( _rText.Copy( _nStartIndex, _nLength ) );
+ return;
+ }
+
+ sal_Int32* pCharWidths = new sal_Int32[ _nLength ];
+ long nTextWidth = GetTextArray( _rText, pCharWidths, _nStartIndex, _nLength );
+ m_rTargetDevice.DrawTextArray( _rStartPoint, _rText, pCharWidths, _nStartIndex, _nLength );
+ delete[] pCharWidths;
+
+ m_aCompleteTextRect.Union( Rectangle( _rStartPoint, Size( nTextWidth, m_rTargetDevice.GetTextHeight() ) ) );
+ }
+
+ //--------------------------------------------------------------------
+ bool ReferenceDeviceTextLayout::GetCaretPositions( const XubString& _rText, sal_Int32* _pCaretXArray,
+ xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) )
+ return false;
+
+ // retrieve the caret positions from the reference device
+ if ( !m_rReferenceDevice.GetCaretPositions( _rText, _pCaretXArray, _nStartIndex, _nLength ) )
+ return false;
+
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ xub_StrLen ReferenceDeviceTextLayout::GetTextBreak( const XubString& _rText, long _nMaxTextWidth, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const
+ {
+ if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) )
+ return 0;
+
+ return m_rReferenceDevice.GetTextBreak( _rText, _nMaxTextWidth, _nStartIndex, _nLength );
+ }
+
+ //--------------------------------------------------------------------
+ bool ReferenceDeviceTextLayout::DecomposeTextRectAction() const
+ {
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ long zoomBy( long _value, const Fraction& _zoom )
+ {
+ double n = (double)_value;
+ n *= (double)_zoom.GetNumerator();
+ n /= (double)_zoom.GetDenominator();
+ return (long)::rtl::math::round( n );
+ }
+ long unzoomBy( long _value, const Fraction& _zoom )
+ {
+ return zoomBy( _value, Fraction( _zoom.GetDenominator(), _zoom.GetNumerator() ) );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Rectangle ReferenceDeviceTextLayout::DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText )
+ {
+ if ( !_rText.Len() )
+ return Rectangle();
+
+ // determine text layout mode from the RTL-ness of the control whose text we render
+ ULONG nTextLayoutMode = m_bRTLEnabled ? TEXT_LAYOUT_BIDI_RTL : TEXT_LAYOUT_BIDI_LTR;
+ 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 ) );
+
+ onBeginDrawText();
+ m_rTargetDevice.DrawText( aRect, _rText, _nStyle, _pVector, _pDisplayText, this );
+ Rectangle aTextRect = onEndDrawText();
+
+ if ( aTextRect.IsEmpty() && !aRect.IsEmpty() )
+ {
+ // this happens for instance if we're in a PaintToDevice call, where only a MetaFile is recorded,
+ // but no actual painting happens, so our "DrawText( Point, ... )" is never called
+ // In this case, calculate the rect from what OutputDevice::GetTextRect would give us. This has
+ // the disadvantage of less accuracy, compared with the approach to calculate the rect from the
+ // single "DrawText( Point, ... )" calls, since more intermediate arithmetics will translate
+ // from ref- to target-units.
+ aTextRect = m_rTargetDevice.GetTextRect( aRect, _rText, _nStyle, NULL, this );
+ }
+
+ // 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 );
+
+ // convert the metric vector
+ if ( _pVector )
+ {
+ for ( MetricVector::iterator charRect = _pVector->begin();
+ charRect != _pVector->end();
+ ++charRect
+ )
+ {
+ *charRect = m_rTargetDevice.LogicToPixel( *charRect );
+ }
+ }
+
+ return aTextRect;
+ }
+
+ //====================================================================
+ //= ControlTextRenderer
+ //====================================================================
+ //--------------------------------------------------------------------
+ ControlTextRenderer::ControlTextRenderer( const Control& _rControl, OutputDevice& _rTargetDevice, OutputDevice& _rReferenceDevice )
+ :m_pImpl( new ReferenceDeviceTextLayout( _rControl, _rTargetDevice, _rReferenceDevice ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ControlTextRenderer::~ControlTextRenderer()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ Rectangle ControlTextRenderer::DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle,
+ MetricVector* _pVector, String* _pDisplayText )
+ {
+ return m_pImpl->DrawText( _rRect, _rText, _nStyle, _pVector, _pDisplayText );
+ }
+
+//........................................................................
+} // namespace vcl
+//........................................................................
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index 4aaef6a707b1..ede3bcc107aa 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -1320,8 +1320,13 @@ void StatusBar::SetItemText( USHORT nItemId, const XubString& rText )
// adjust item width - see also DataChanged()
long nFudge = GetTextHeight()/4;
long nWidth = GetTextWidth( pItem->maText ) + nFudge;
- if( nWidth > pItem->mnWidth + STATUSBAR_OFFSET )
+ if( (nWidth > pItem->mnWidth + STATUSBAR_OFFSET) ||
+ ((nWidth < pItem->mnWidth) && (mnDX - STATUSBAR_OFFSET) < mnItemsWidth ))
+ {
pItem->mnWidth = nWidth + STATUSBAR_OFFSET;
+ ImplFormat();
+ Invalidate();
+ }
// Item neu Zeichen, wenn StatusBar sichtbar und
// UpdateMode gesetzt ist
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 63bf407ce49f..371f962c45ac 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -9752,6 +9752,8 @@ void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rP
EnableOutput();
DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
+ if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
+ return;
// preserve graphicsstate
Push();