xref: /aoo41x/main/sw/source/core/layout/virtoutp.cxx (revision efeef26f)
1*efeef26fSAndrew Rist /**************************************************************
2*efeef26fSAndrew Rist  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*efeef26fSAndrew Rist  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19*efeef26fSAndrew Rist  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <vcl/window.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "hintids.hxx"
31cdf0e10cSrcweir #include "viewsh.hxx"
32cdf0e10cSrcweir #include "virtoutp.hxx"
33cdf0e10cSrcweir #include "viewopt.hxx"
34cdf0e10cSrcweir #include "rootfrm.hxx"
35cdf0e10cSrcweir // OD 12.11.2002 #96272# - include declaration for <SetMappingForVirtDev>
36cdf0e10cSrcweir #include "setmapvirtdev.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #ifdef DBG_UTIL
39cdf0e10cSrcweir 
40cdf0e10cSrcweir /*************************************************************************
41cdf0e10cSrcweir  *							class DbgRect
42cdf0e10cSrcweir  *************************************************************************/
43cdf0e10cSrcweir 
44cdf0e10cSrcweir class DbgRect
45cdf0e10cSrcweir {
46cdf0e10cSrcweir 		OutputDevice *pOut;
47cdf0e10cSrcweir public:
48cdf0e10cSrcweir 		DbgRect( OutputDevice *pOut, const Rectangle &rRect,
49cdf0e10cSrcweir 				 const ColorData eColor = COL_LIGHTBLUE );
50cdf0e10cSrcweir };
51cdf0e10cSrcweir 
DbgRect(OutputDevice * pOutDev,const Rectangle & rRect,const ColorData eColor)52cdf0e10cSrcweir inline DbgRect::DbgRect( OutputDevice *pOutDev, const Rectangle &rRect,
53cdf0e10cSrcweir 						 const ColorData eColor )
54cdf0e10cSrcweir    :pOut( pOutDev )
55cdf0e10cSrcweir {
56cdf0e10cSrcweir 	if( pOut )
57cdf0e10cSrcweir 	{
58cdf0e10cSrcweir 		pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
59cdf0e10cSrcweir 		pOut->SetLineColor( eColor );
60cdf0e10cSrcweir 		pOut->SetFillColor();
61cdf0e10cSrcweir 		pOut->DrawRect( rRect );
62cdf0e10cSrcweir 		pOut->Pop();
63cdf0e10cSrcweir 	}
64cdf0e10cSrcweir }
65cdf0e10cSrcweir 
66cdf0e10cSrcweir #endif
67cdf0e10cSrcweir 
68cdf0e10cSrcweir /* class SwLayVout verwaltet das virtuelle Outputdevice
69cdf0e10cSrcweir  * Es gibt von dieser Klasse einen statischen Member am RootFrm,
70cdf0e10cSrcweir  * dieser wird in _FrmInit angelegt und in _FrmFinit zerstoert.
71cdf0e10cSrcweir  * */
72cdf0e10cSrcweir 
FlushVout()73cdf0e10cSrcweir sal_Bool SwRootFrm::FlushVout()
74cdf0e10cSrcweir {
75cdf0e10cSrcweir 	if( SwRootFrm::pVout->IsFlushable() )
76cdf0e10cSrcweir 	{
77cdf0e10cSrcweir 		SwRootFrm::pVout->_Flush();
78cdf0e10cSrcweir 		return sal_True;
79cdf0e10cSrcweir 	}
80cdf0e10cSrcweir 	return sal_False;
81cdf0e10cSrcweir }
82cdf0e10cSrcweir 
HasSameRect(const SwRect & rRect)83cdf0e10cSrcweir sal_Bool SwRootFrm::HasSameRect( const SwRect& rRect )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir 	if( SwRootFrm::pVout->IsFlushable() )
86cdf0e10cSrcweir 		return ( rRect == SwRootFrm::pVout->GetOrgRect() );
87cdf0e10cSrcweir 	return sal_False;
88cdf0e10cSrcweir }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir /** method to set mapping/pixel offset for virtual output device
91cdf0e10cSrcweir 
92cdf0e10cSrcweir     OD 12.11.2002 #96272# - method implements two solutions for the mapping of
93cdf0e10cSrcweir     the virtual output device:
94cdf0e10cSrcweir     The old solution set the origin of the mapping mode, which will be used in
95cdf0e10cSrcweir     the virtual output device. This causes several paint errors, because of the
96cdf0e10cSrcweir     different roundings in the virtual output device and the original output device.
97cdf0e10cSrcweir     The new solution avoids the rounding differences between virtual and original
98cdf0e10cSrcweir     output device by setting a pixel offset at the virtual output device.
99cdf0e10cSrcweir     A define controls, which solution is used, in order to switch in escalation
100cdf0e10cSrcweir     back to old solution.
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     @author OD
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     @param _pOrgOutDev
105cdf0e10cSrcweir     input parameter - constant instance of the original output device, for which
106cdf0e10cSrcweir     the virtual output device is created.
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     @param _pVirDev
109cdf0e10cSrcweir     input/output parameter - instance of the virtual output device.
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     @param _pMapMode
112cdf0e10cSrcweir     input/output parameter - instance of the mapping mode, which will be set
113cdf0e10cSrcweir     at the virtual output device.
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     @param _rNewOrigin
116cdf0e10cSrcweir     input parameter - constant instance of the origin, which will be used in
117cdf0e10cSrcweir     the virtual output device
118cdf0e10cSrcweir */
119cdf0e10cSrcweir // define to control, if old or new solution for setting the mapping for
120cdf0e10cSrcweir // an virtual output device is used.
SetMappingForVirtDev(const Point & _rNewOrigin,MapMode *,const OutputDevice * _pOrgOutDev,VirtualDevice * _pVirDev)121cdf0e10cSrcweir void SetMappingForVirtDev(  const Point&    _rNewOrigin,
122cdf0e10cSrcweir                             MapMode*        ,
123cdf0e10cSrcweir                             const OutputDevice* _pOrgOutDev,
124cdf0e10cSrcweir                             VirtualDevice*  _pVirDev )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir         // new solution: set pixel offset at virtual output device
127cdf0e10cSrcweir         Point aPixelOffset = _pOrgOutDev->LogicToPixel( _rNewOrigin );
128cdf0e10cSrcweir         _pVirDev->SetPixelOffset( Size( -aPixelOffset.X(), -aPixelOffset.Y() ) );
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 
132cdf0e10cSrcweir /*************************************************************************
133cdf0e10cSrcweir  *							SwVOut::DoesFit()
134cdf0e10cSrcweir  *************************************************************************/
135cdf0e10cSrcweir 
136cdf0e10cSrcweir // rSize muss in Pixel-Koordinaten vorliegen!
DoesFit(const Size & rNew)137cdf0e10cSrcweir sal_Bool SwLayVout::DoesFit( const Size &rNew )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	if( rNew.Height() > VIRTUALHEIGHT )
140cdf0e10cSrcweir 		return sal_False;
141cdf0e10cSrcweir 	if( rNew.Width() <= 0 || rNew.Height() <= 0 )
142cdf0e10cSrcweir 		return sal_False;
143cdf0e10cSrcweir 	if( rNew.Width() <= aSize.Width() )
144cdf0e10cSrcweir 		return sal_True;
145cdf0e10cSrcweir 	if( !pVirDev )
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		pVirDev = new VirtualDevice();
148cdf0e10cSrcweir 		pVirDev->SetLineColor();
149cdf0e10cSrcweir 		if( pOut )
150cdf0e10cSrcweir 		{
151cdf0e10cSrcweir 			if( pVirDev->GetFillColor() != pOut->GetFillColor() )
152cdf0e10cSrcweir 				pVirDev->SetFillColor( pOut->GetFillColor() );
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 	if( rNew.Width() > aSize.Width() )
157cdf0e10cSrcweir 	{
158cdf0e10cSrcweir 		aSize.Width() = rNew.Width();
159cdf0e10cSrcweir 		if( !pVirDev->SetOutputSizePixel( aSize ) )
160cdf0e10cSrcweir 		{
161cdf0e10cSrcweir 			delete pVirDev;
162cdf0e10cSrcweir 			pVirDev = NULL;
163cdf0e10cSrcweir 			aSize.Width() = 0;
164cdf0e10cSrcweir 			return sal_False;
165cdf0e10cSrcweir 		}
166cdf0e10cSrcweir 	}
167cdf0e10cSrcweir 	return sal_True;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir /*************************************************************************
171cdf0e10cSrcweir  *						   SwLayVout::Enter
172cdf0e10cSrcweir  *************************************************************************/
173cdf0e10cSrcweir /// OD 27.09.2002 #103636# - change 2nd parameter <rRect> - no longer <const>
174cdf0e10cSrcweir ///     in order to return value of class member variable <aRect>, if virtual
175cdf0e10cSrcweir ///     output is used.
176cdf0e10cSrcweir ///     <aRect> contains the rectangle that represents the area the virtual
177cdf0e10cSrcweir ///     output device is used for and that is flushed at the end.
Enter(ViewShell * pShell,SwRect & rRect,sal_Bool bOn)178cdf0e10cSrcweir void SwLayVout::Enter(  ViewShell *pShell, SwRect &rRect, sal_Bool bOn )
179cdf0e10cSrcweir {
180cdf0e10cSrcweir     Flush();
181cdf0e10cSrcweir 
182cdf0e10cSrcweir #ifdef DBG_UTIL
183cdf0e10cSrcweir 		if( pShell->GetViewOptions()->IsTest3() )
184cdf0e10cSrcweir 		{
185cdf0e10cSrcweir 			++nCount;
186cdf0e10cSrcweir 			return;
187cdf0e10cSrcweir 		}
188cdf0e10cSrcweir #endif
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 	bOn = bOn && !nCount && rRect.HasArea() && pShell->GetWin();
191cdf0e10cSrcweir 	++nCount;
192cdf0e10cSrcweir 	if( bOn )
193cdf0e10cSrcweir 	{
194cdf0e10cSrcweir 		pSh = pShell;
195cdf0e10cSrcweir 		pOut = NULL;
196cdf0e10cSrcweir 		OutputDevice *pO = pSh->GetOut();
197cdf0e10cSrcweir // Auf dem Drucker oder einem virt. Outputdevice wird nicht getrickst...
198cdf0e10cSrcweir 		if( OUTDEV_WINDOW != pO->GetOutDevType() )
199cdf0e10cSrcweir 			return;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 		pOut = pO;
202cdf0e10cSrcweir 		Size aPixSz( pOut->PixelToLogic( Size( 1,1 )) );
203cdf0e10cSrcweir 		SwRect aTmp( rRect );
204cdf0e10cSrcweir 		aTmp.SSize().Width() += aPixSz.Width()/2 + 1;
205cdf0e10cSrcweir 		aTmp.SSize().Height()+= aPixSz.Height()/2 + 1;
206cdf0e10cSrcweir 		Rectangle aTmpRect( pO->LogicToPixel( aTmp.SVRect() ) );
207cdf0e10cSrcweir 
208cdf0e10cSrcweir         ASSERT( !pSh->GetWin()->IsReallyVisible() ||
209cdf0e10cSrcweir                 aTmpRect.GetWidth() <= pSh->GetWin()->GetOutputSizePixel().Width() + 2,
210cdf0e10cSrcweir 				"Paintwidth bigger than visarea?" );
211cdf0e10cSrcweir 		// Passt das Rechteck in unseren Buffer ?
212cdf0e10cSrcweir 		if( !DoesFit( aTmpRect.GetSize() ) )
213cdf0e10cSrcweir 		{
214cdf0e10cSrcweir 			pOut = NULL;
215cdf0e10cSrcweir 			return;
216cdf0e10cSrcweir 		}
217cdf0e10cSrcweir 
218cdf0e10cSrcweir         aRect = SwRect( pO->PixelToLogic( aTmpRect ) );
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 		SetOutDev( pSh, pVirDev );
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 		if( pVirDev->GetFillColor() != pOut->GetFillColor() )
223cdf0e10cSrcweir 			pVirDev->SetFillColor( pOut->GetFillColor() );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         MapMode aMapMode( pOut->GetMapMode() );
226cdf0e10cSrcweir         // OD 12.11.2002 #96272# - use method to set mapping
227cdf0e10cSrcweir         //aMapMode.SetOrigin( Point(0,0) - aRect.Pos() );
228cdf0e10cSrcweir         ::SetMappingForVirtDev( aRect.Pos(), &aMapMode, pOut, pVirDev );
229cdf0e10cSrcweir 
230cdf0e10cSrcweir         if( aMapMode != pVirDev->GetMapMode() )
231cdf0e10cSrcweir 			pVirDev->SetMapMode( aMapMode );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir         /// OD 27.09.2002 #103636# - set value of parameter <rRect>
234cdf0e10cSrcweir         rRect = aRect;
235cdf0e10cSrcweir 	}
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir /*************************************************************************
239cdf0e10cSrcweir  *						   SwLayVout::Flush()
240cdf0e10cSrcweir  *************************************************************************/
241cdf0e10cSrcweir 
_Flush()242cdf0e10cSrcweir void SwLayVout::_Flush()
243cdf0e10cSrcweir {
244cdf0e10cSrcweir 	ASSERT( pVirDev, "SwLayVout::DrawOut: nothing left Toulouse" );
245cdf0e10cSrcweir 	Rectangle aTmp( aRect.SVRect() );
246cdf0e10cSrcweir     pOut->DrawOutDev( aRect.Pos(), aRect.SSize(),
247cdf0e10cSrcweir                       aRect.Pos(), aRect.SSize(), *pVirDev );
248cdf0e10cSrcweir     SetOutDev( pSh, pOut );
249cdf0e10cSrcweir 	pOut = NULL;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 
253