xref: /aoo42x/main/vcl/source/gdi/salgdilayout.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/ref.hxx>
32 #include <tools/debug.hxx>
33 #include <tools/poly.hxx>
34 
35 #include <vcl/svapp.hxx>
36 #include <vcl/region.hxx>
37 #include <vcl/virdev.hxx>
38 #include <vcl/window.hxx>
39 #include <vcl/metaact.hxx>
40 #include <vcl/gdimtf.hxx>
41 #include <vcl/print.hxx>
42 #include <vcl/outdev.hxx>
43 #include <vcl/unowrap.hxx>
44 
45 #include <window.h>
46 #include <region.h>
47 #include <outdev.h>
48 #include <sallayout.hxx>
49 #include <salgdi.hxx>
50 #include <salframe.hxx>
51 #include <salvd.hxx>
52 #include <salprn.hxx>
53 #include <svdata.hxx>
54 #include <outdata.hxx>
55 
56 
57 #include "basegfx/polygon/b2dpolygon.hxx"
58 
59 // ----------------------------------------------------------------------------
60 // The only common SalFrame method
61 // ----------------------------------------------------------------------------
62 
63 SalFrameGeometry SalFrame::GetGeometry()
64 {
65     // mirror frame coordinates at parent
66     SalFrame *pParent = GetParent();
67     if( pParent && Application::GetSettings().GetLayoutRTL() )
68     {
69         SalFrameGeometry aGeom = maGeometry;
70         int parent_x = aGeom.nX - pParent->maGeometry.nX;
71         aGeom.nX = pParent->maGeometry.nX + pParent->maGeometry.nWidth - maGeometry.nWidth - parent_x;
72         return aGeom;
73     }
74     else
75         return maGeometry;
76 }
77 
78 // ----------------------------------------------------------------------------
79 
80 SalGraphics::SalGraphics()
81 :   m_nLayout( 0 ),
82     m_bAntiAliasB2DDraw(false)
83 {
84     // read global RTL settings
85     if( Application::GetSettings().GetLayoutRTL() )
86 	    m_nLayout = SAL_LAYOUT_BIDI_RTL;
87 }
88 
89 SalGraphics::~SalGraphics()
90 {
91 }
92 
93 // ----------------------------------------------------------------------------
94 
95 bool SalGraphics::drawAlphaBitmap( const SalTwoRect&,
96     const SalBitmap&, const SalBitmap& )
97 {
98     return false;
99 }
100 
101 // ----------------------------------------------------------------------------
102 
103 void SalGraphics::mirror( long& x, const OutputDevice *pOutDev, bool bBack ) const
104 {
105 	long w;
106     if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
107         w = pOutDev->GetOutputWidthPixel();
108     else
109         w = GetGraphicsWidth();
110 
111 	if( w )
112     {
113         if( pOutDev && pOutDev->ImplIsAntiparallel() )
114         {
115             OutputDevice *pOutDevRef = (OutputDevice*) pOutDev;
116             // mirror this window back
117             if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
118             {
119                 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
120                 if( bBack )
121                     x = x - devX + pOutDevRef->GetOutOffXPixel();
122                 else
123                     x = devX + (x - pOutDevRef->GetOutOffXPixel());
124             }
125             else
126             {
127                 long devX = pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
128                 if( bBack )
129                     x = x - pOutDevRef->GetOutputWidthPixel() + devX - pOutDevRef->GetOutOffXPixel() + 1;
130                 else
131                     x = pOutDevRef->GetOutputWidthPixel() - (x - devX) + pOutDevRef->GetOutOffXPixel() - 1;
132             }
133         }
134         else if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
135 		    x = w-1-x;
136     }
137 }
138 
139 void SalGraphics::mirror( long& x, long& nWidth, const OutputDevice *pOutDev, bool bBack ) const
140 {
141 	long w;
142     if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
143         w = pOutDev->GetOutputWidthPixel();
144     else
145         w = GetGraphicsWidth();
146 
147 	if( w )
148     {
149         if( pOutDev && pOutDev->ImplIsAntiparallel() )
150         {
151             OutputDevice *pOutDevRef = (OutputDevice*) pOutDev;
152             // mirror this window back
153             if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
154             {
155                 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
156                 if( bBack )
157                     x = x - devX + pOutDevRef->GetOutOffXPixel();
158                 else
159                     x = devX + (x - pOutDevRef->GetOutOffXPixel());
160             }
161             else
162             {
163                 long devX = pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
164                 if( bBack )
165                     x = x - pOutDevRef->GetOutputWidthPixel() + devX - pOutDevRef->GetOutOffXPixel() + nWidth;
166                 else
167                     x = pOutDevRef->GetOutputWidthPixel() - (x - devX) + pOutDevRef->GetOutOffXPixel() - nWidth;
168             }
169         }
170         else if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
171 		    x = w-nWidth-x;
172 
173     }
174 }
175 
176 sal_Bool SalGraphics::mirror( sal_uInt32 nPoints, const SalPoint *pPtAry, SalPoint *pPtAry2, const OutputDevice *pOutDev, bool bBack ) const
177 {
178 	long w;
179     if( pOutDev && pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
180         w = pOutDev->GetOutputWidthPixel();
181     else
182         w = GetGraphicsWidth();
183 
184 	if( w )
185 	{
186 		sal_uInt32 i, j;
187 
188         if( pOutDev && pOutDev->ImplIsAntiparallel() )
189         {
190             OutputDevice *pOutDevRef = (OutputDevice*) pOutDev;
191             // mirror this window back
192             if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
193             {
194                 long devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
195                 if( bBack )
196                 {
197                     for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
198                     {
199                         //long x = w-1-pPtAry[i].mnX;
200                         //pPtAry2[j].mnX = devX + ( pOutDevRef->mnOutWidth - 1 - (x - devX) );
201                         pPtAry2[j].mnX = pOutDevRef->GetOutOffXPixel() + (pPtAry[i].mnX - devX);
202                         pPtAry2[j].mnY = pPtAry[i].mnY;
203                     }
204                 }
205                 else
206                 {
207                     for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
208                     {
209                         //long x = w-1-pPtAry[i].mnX;
210                         //pPtAry2[j].mnX = devX + ( pOutDevRef->mnOutWidth - 1 - (x - devX) );
211                         pPtAry2[j].mnX = devX + (pPtAry[i].mnX - pOutDevRef->GetOutOffXPixel());
212                         pPtAry2[j].mnY = pPtAry[i].mnY;
213                     }
214                 }
215             }
216             else
217             {
218                 long devX = pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
219                 if( bBack )
220                 {
221                     for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
222                     {
223                         //long x = w-1-pPtAry[i].mnX;
224                         //pPtAry2[j].mnX = devX + ( pOutDevRef->mnOutWidth - 1 - (x - devX) );
225                         pPtAry2[j].mnX = pPtAry[i].mnX - pOutDevRef->GetOutputWidthPixel() + devX - pOutDevRef->GetOutOffXPixel() + 1;
226                         pPtAry2[j].mnY = pPtAry[i].mnY;
227                     }
228                 }
229                 else
230                 {
231                     for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
232                     {
233                         //long x = w-1-pPtAry[i].mnX;
234                         //pPtAry2[j].mnX = devX + ( pOutDevRef->mnOutWidth - 1 - (x - devX) );
235                         pPtAry2[j].mnX = pOutDevRef->GetOutputWidthPixel() - (pPtAry[i].mnX - devX) + pOutDevRef->GetOutOffXPixel() - 1;
236                         pPtAry2[j].mnY = pPtAry[i].mnY;
237                     }
238                 }
239             }
240         }
241         else if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) )
242         {
243 		    for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
244 		    {
245 			    pPtAry2[j].mnX = w-1-pPtAry[i].mnX;
246 			    pPtAry2[j].mnY = pPtAry[i].mnY;
247 		    }
248         }
249 		return sal_True;
250 	}
251 	else
252 		return sal_False;
253 }
254 
255 void SalGraphics::mirror( Region& rRgn, const OutputDevice *pOutDev, bool bBack ) const
256 {
257     if( rRgn.HasPolyPolygon() )
258     {
259         basegfx::B2DPolyPolygon aPolyPoly( rRgn.ConvertToB2DPolyPolygon() );
260         aPolyPoly = mirror( aPolyPoly, pOutDev, bBack );
261         rRgn = Region( aPolyPoly );
262     }
263     else
264     {
265         ImplRegionInfo		aInfo;
266         bool				bRegionRect;
267         Region              aMirroredRegion;
268         long nX, nY, nWidth, nHeight;
269 
270         bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
271         while ( bRegionRect )
272         {
273             Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
274             mirror( aRect, pOutDev, bBack );
275             aMirroredRegion.Union( aRect );
276             bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
277         }
278         rRgn = aMirroredRegion;
279     }
280 }
281 
282 void SalGraphics::mirror( Rectangle& rRect, const OutputDevice *pOutDev, bool bBack ) const
283 {
284     long nWidth = rRect.GetWidth();
285     long x      = rRect.Left();
286     long x_org = x;
287 
288     mirror( x, nWidth, pOutDev, bBack );
289     rRect.Move( x - x_org, 0 );
290 }
291 
292 basegfx::B2DPoint SalGraphics::mirror( const basegfx::B2DPoint& i_rPoint, const OutputDevice *i_pOutDev, bool i_bBack ) const
293 {
294 	long w;
295     if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
296         w = i_pOutDev->GetOutputWidthPixel();
297     else
298         w = GetGraphicsWidth();
299 
300     DBG_ASSERT( w, "missing graphics width" );
301 
302     basegfx::B2DPoint aRet( i_rPoint );
303 	if( w )
304     {
305         if( i_pOutDev && !i_pOutDev->IsRTLEnabled() )
306         {
307             OutputDevice *pOutDevRef = (OutputDevice*)i_pOutDev;
308             // mirror this window back
309             double devX = w-pOutDevRef->GetOutputWidthPixel()-pOutDevRef->GetOutOffXPixel();   // re-mirrored mnOutOffX
310             if( i_bBack )
311                 aRet.setX( i_rPoint.getX() - devX + pOutDevRef->GetOutOffXPixel() );
312             else
313                 aRet.setX( devX + (i_rPoint.getX() - pOutDevRef->GetOutOffXPixel()) );
314         }
315         else
316 		    aRet.setX( w-1-i_rPoint.getX() );
317     }
318     return aRet;
319 }
320 
321 basegfx::B2DPolygon SalGraphics::mirror( const basegfx::B2DPolygon& i_rPoly, const OutputDevice *i_pOutDev, bool i_bBack ) const
322 {
323 	long w;
324     if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
325         w = i_pOutDev->GetOutputWidthPixel();
326     else
327         w = GetGraphicsWidth();
328 
329     DBG_ASSERT( w, "missing graphics width" );
330 
331     basegfx::B2DPolygon aRet;
332 	if( w )
333     {
334         sal_Int32 nPoints = i_rPoly.count();
335         for( sal_Int32 i = 0; i < nPoints; i++ )
336         {
337             aRet.append( mirror( i_rPoly.getB2DPoint( i ), i_pOutDev, i_bBack ) );
338             if( i_rPoly.isPrevControlPointUsed( i ) )
339                 aRet.setPrevControlPoint( i, mirror( i_rPoly.getPrevControlPoint( i ), i_pOutDev, i_bBack ) );
340             if( i_rPoly.isNextControlPointUsed( i ) )
341                 aRet.setNextControlPoint( i, mirror( i_rPoly.getNextControlPoint( i ), i_pOutDev, i_bBack ) );
342         }
343         aRet.setClosed( i_rPoly.isClosed() );
344         aRet.flip();
345     }
346     else
347         aRet = i_rPoly;
348     return aRet;
349 }
350 
351 basegfx::B2DPolyPolygon SalGraphics::mirror( const basegfx::B2DPolyPolygon& i_rPoly, const OutputDevice *i_pOutDev, bool i_bBack ) const
352 {
353 	long w;
354     if( i_pOutDev && i_pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
355         w = i_pOutDev->GetOutputWidthPixel();
356     else
357         w = GetGraphicsWidth();
358 
359     DBG_ASSERT( w, "missing graphics width" );
360 
361     basegfx::B2DPolyPolygon aRet;
362 	if( w )
363     {
364         sal_Int32 nPoly = i_rPoly.count();
365         for( sal_Int32 i = 0; i < nPoly; i++ )
366             aRet.append( mirror( i_rPoly.getB2DPolygon( i ), i_pOutDev, i_bBack ) );
367         aRet.setClosed( i_rPoly.isClosed() );
368         aRet.flip();
369     }
370     else
371         aRet = i_rPoly;
372     return aRet;
373 }
374 
375 // ----------------------------------------------------------------------------
376 
377 bool SalGraphics::SetClipRegion( const Region& i_rClip, const OutputDevice *pOutDev )
378 {
379 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
380 	{
381 	    Region aMirror( i_rClip );
382 		mirror( aMirror, pOutDev );
383 		return setClipRegion( aMirror );
384 	}
385 	return setClipRegion( i_rClip );
386 }
387 
388 void	SalGraphics::DrawPixel( long nX, long nY, const OutputDevice *pOutDev )
389 {
390 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
391 		mirror( nX, pOutDev );
392 	drawPixel( nX, nY );
393 }
394 void	SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor, const OutputDevice *pOutDev )
395 {
396 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
397 		mirror( nX, pOutDev );
398 	drawPixel( nX, nY, nSalColor );
399 }
400 void	SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2, const OutputDevice *pOutDev )
401 {
402 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
403 	{
404 		mirror( nX1, pOutDev );
405 		mirror( nX2, pOutDev );
406 	}
407 	drawLine( nX1, nY1, nX2, nY2 );
408 }
409 void	SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev )
410 {
411 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
412 		mirror( nX, nWidth, pOutDev );
413 	drawRect( nX, nY, nWidth, nHeight );
414 }
415 bool SalGraphics::drawPolyLine(
416     const basegfx::B2DPolygon& /*rPolyPolygon*/,
417     double /*fTransparency*/,
418     const basegfx::B2DVector& /*rLineWidths*/,
419     basegfx::B2DLineJoin /*eLineJoin*/)
420 {
421     return false;
422 }
423 
424 void SalGraphics::DrawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry, const OutputDevice *pOutDev )
425 {
426 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
427 	{
428 		SalPoint* pPtAry2 = new SalPoint[nPoints];
429 		sal_Bool bCopied = mirror( nPoints, pPtAry, pPtAry2, pOutDev );
430 		drawPolyLine( nPoints, bCopied ? pPtAry2 : pPtAry );
431 		delete [] pPtAry2;
432 	}
433 	else
434 		drawPolyLine( nPoints, pPtAry );
435 }
436 
437 void SalGraphics::DrawPolygon( sal_uLong nPoints, const SalPoint* pPtAry, const OutputDevice *pOutDev )
438 {
439 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
440 	{
441 		SalPoint* pPtAry2 = new SalPoint[nPoints];
442 		sal_Bool bCopied = mirror( nPoints, pPtAry, pPtAry2, pOutDev );
443 		drawPolygon( nPoints, bCopied ? pPtAry2 : pPtAry );
444 		delete [] pPtAry2;
445 	}
446 	else
447 		drawPolygon( nPoints, pPtAry );
448 }
449 
450 void SalGraphics::DrawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry, const OutputDevice *pOutDev )
451 {
452 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
453 	{
454         // TODO: optimize, reduce new/delete calls
455         SalPoint **pPtAry2 = new SalPoint*[nPoly];
456         sal_uLong i;
457         for(i=0; i<nPoly; i++)
458         {
459             sal_uLong nPoints = pPoints[i];
460             pPtAry2[i] = new SalPoint[ nPoints ];
461 		    mirror( nPoints, pPtAry[i], pPtAry2[i], pOutDev );
462         }
463 
464         drawPolyPolygon( nPoly, pPoints, (PCONSTSALPOINT*)pPtAry2 );
465 
466         for(i=0; i<nPoly; i++)
467             delete [] pPtAry2[i];
468         delete [] pPtAry2;
469     }
470     else
471 	    drawPolyPolygon( nPoly, pPoints, pPtAry );
472 }
473 
474 bool SalGraphics::DrawPolyPolygon( const ::basegfx::B2DPolyPolygon& i_rPolyPolygon, double i_fTransparency, const OutputDevice* i_pOutDev )
475 {
476     bool bRet = false;
477 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
478 	{
479         basegfx::B2DPolyPolygon aMirror( mirror( i_rPolyPolygon, i_pOutDev ) );
480         bRet = drawPolyPolygon( aMirror, i_fTransparency );
481     }
482     else
483         bRet = drawPolyPolygon( i_rPolyPolygon, i_fTransparency );
484     return bRet;
485 }
486 
487 bool SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/)
488 {
489 	return false;
490 }
491 
492 sal_Bool SalGraphics::DrawPolyLineBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry, const OutputDevice* pOutDev )
493 {
494     sal_Bool bResult = sal_False;
495 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
496 	{
497 		SalPoint* pPtAry2 = new SalPoint[nPoints];
498 		sal_Bool bCopied = mirror( nPoints, pPtAry, pPtAry2, pOutDev );
499 		bResult = drawPolyLineBezier( nPoints, bCopied ? pPtAry2 : pPtAry, pFlgAry );
500 		delete [] pPtAry2;
501 	}
502 	else
503         bResult = drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
504     return bResult;
505 }
506 
507 sal_Bool SalGraphics::DrawPolygonBezier( sal_uLong nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry, const OutputDevice* pOutDev )
508 {
509     sal_Bool bResult = sal_False;
510 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
511 	{
512 		SalPoint* pPtAry2 = new SalPoint[nPoints];
513 		sal_Bool bCopied = mirror( nPoints, pPtAry, pPtAry2, pOutDev );
514 		bResult = drawPolygonBezier( nPoints, bCopied ? pPtAry2 : pPtAry, pFlgAry );
515 		delete [] pPtAry2;
516 	}
517 	else
518         bResult = drawPolygonBezier( nPoints, pPtAry, pFlgAry );
519     return bResult;
520 }
521 
522 sal_Bool SalGraphics::DrawPolyPolygonBezier( sal_uInt32 i_nPoly, const sal_uInt32* i_pPoints,
523                                                    const SalPoint* const* i_pPtAry, const sal_uInt8* const* i_pFlgAry, const OutputDevice* i_pOutDev )
524 {
525     sal_Bool bRet = sal_False;
526 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
527 	{
528         // TODO: optimize, reduce new/delete calls
529         SalPoint **pPtAry2 = new SalPoint*[i_nPoly];
530         sal_uLong i;
531         for(i=0; i<i_nPoly; i++)
532         {
533             sal_uLong nPoints = i_pPoints[i];
534             pPtAry2[i] = new SalPoint[ nPoints ];
535 		    mirror( nPoints, i_pPtAry[i], pPtAry2[i], i_pOutDev );
536         }
537 
538         bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, (PCONSTSALPOINT*)pPtAry2, i_pFlgAry );
539 
540         for(i=0; i<i_nPoly; i++)
541             delete [] pPtAry2[i];
542         delete [] pPtAry2;
543     }
544     else
545 	    bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, i_pPtAry, i_pFlgAry );
546     return bRet;
547 }
548 
549 bool SalGraphics::DrawPolyLine( const ::basegfx::B2DPolygon& i_rPolygon, double fTransparency,
550     const ::basegfx::B2DVector& i_rLineWidth, basegfx::B2DLineJoin i_eLineJoin,
551     const OutputDevice* i_pOutDev )
552 {
553     bool bRet = false;
554 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) )
555 	{
556         basegfx::B2DPolygon aMirror( mirror( i_rPolygon, i_pOutDev ) );
557         bRet = drawPolyLine( aMirror, fTransparency, i_rLineWidth, i_eLineJoin );
558     }
559     else
560         bRet = drawPolyLine( i_rPolygon, fTransparency, i_rLineWidth, i_eLineJoin );
561     return bRet;
562 }
563 
564 void	SalGraphics::CopyArea( long nDestX, long nDestY,
565                                long nSrcX, long nSrcY,
566                                long nSrcWidth, long nSrcHeight,
567                                sal_uInt16 nFlags, const OutputDevice *pOutDev )
568 {
569 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
570 	{
571 		mirror( nDestX, nSrcWidth, pOutDev );
572 		mirror( nSrcX, nSrcWidth, pOutDev );
573 	}
574 	copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, nFlags );
575 }
576 void	SalGraphics::CopyBits( const SalTwoRect* pPosAry,
577                                SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev )
578 {
579 	if( ( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) ||
580         (pSrcGraphics && ( (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)  || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) ) )
581 	{
582 		SalTwoRect pPosAry2 = *pPosAry;
583 		if( (pSrcGraphics && (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) )
584 			mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcOutDev );
585 		if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
586 			mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
587 		copyBits( &pPosAry2, pSrcGraphics );
588 	}
589 	else
590 		copyBits( pPosAry, pSrcGraphics );
591 }
592 void	SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
593 									const SalBitmap& rSalBitmap, const OutputDevice *pOutDev )
594 {
595 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
596 	{
597 		SalTwoRect pPosAry2 = *pPosAry;
598 		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
599 		drawBitmap( &pPosAry2, rSalBitmap );
600 	}
601 	else
602 		drawBitmap( pPosAry, rSalBitmap );
603 }
604 void	SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
605 									const SalBitmap& rSalBitmap,
606 									SalColor nTransparentColor, const OutputDevice *pOutDev )
607 {
608 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
609 	{
610 		SalTwoRect pPosAry2 = *pPosAry;
611 		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
612 		drawBitmap( &pPosAry2, rSalBitmap, nTransparentColor );
613 	}
614 	else
615 		drawBitmap( pPosAry, rSalBitmap, nTransparentColor );
616 }
617 void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
618                               const SalBitmap& rSalBitmap,
619                               const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev )
620 {
621 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
622 	{
623 		SalTwoRect pPosAry2 = *pPosAry;
624 		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
625 		drawBitmap( &pPosAry2, rSalBitmap, rTransparentBitmap );
626 	}
627 	else
628 		drawBitmap( pPosAry, rSalBitmap, rTransparentBitmap );
629 }
630 void	SalGraphics::DrawMask( const SalTwoRect* pPosAry,
631 								  const SalBitmap& rSalBitmap,
632 								  SalColor nMaskColor, const OutputDevice *pOutDev )
633 {
634 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
635 	{
636 		SalTwoRect pPosAry2 = *pPosAry;
637 		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
638 		drawMask( &pPosAry2, rSalBitmap, nMaskColor );
639 	}
640 	else
641 		drawMask( pPosAry, rSalBitmap, nMaskColor );
642 }
643 SalBitmap*	SalGraphics::GetBitmap( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev )
644 {
645 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
646 		mirror( nX, nWidth, pOutDev );
647 	return getBitmap( nX, nY, nWidth, nHeight );
648 }
649 SalColor	SalGraphics::GetPixel( long nX, long nY, const OutputDevice *pOutDev )
650 {
651 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
652 		mirror( nX, pOutDev );
653 	return getPixel( nX, nY );
654 }
655 void	SalGraphics::Invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags, const OutputDevice *pOutDev )
656 {
657 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
658 		mirror( nX, nWidth, pOutDev );
659 	invert( nX, nY, nWidth, nHeight, nFlags );
660 }
661 void	SalGraphics::Invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nFlags, const OutputDevice *pOutDev )
662 {
663 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
664 	{
665 		SalPoint* pPtAry2 = new SalPoint[nPoints];
666 		sal_Bool bCopied = mirror( nPoints, pPtAry, pPtAry2, pOutDev );
667 		invert( nPoints, bCopied ? pPtAry2 : pPtAry, nFlags );
668 		delete [] pPtAry2;
669 	}
670 	else
671 		invert( nPoints, pPtAry, nFlags );
672 }
673 
674 sal_Bool	SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize, const OutputDevice *pOutDev )
675 {
676 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
677 		mirror( nX, nWidth, pOutDev );
678 	return drawEPS( nX, nY, nWidth, nHeight,  pPtr, nSize );
679 }
680 
681 sal_Bool SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
682                                                 const Point& aPos, sal_Bool& rIsInside, const OutputDevice *pOutDev )
683 {
684 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
685     {
686         Point pt( aPos );
687         Rectangle rgn( rControlRegion );
688         mirror( pt.X(), pOutDev );
689         mirror( rgn, pOutDev );
690         return hitTestNativeControl( nType, nPart, rgn, pt, rIsInside );
691     }
692     else
693         return hitTestNativeControl( nType, nPart, rControlRegion, aPos, rIsInside );
694 }
695 
696 void SalGraphics::mirror( ControlType , const ImplControlValue& rVal, const OutputDevice* pOutDev, bool bBack ) const
697 {
698     switch( rVal.getType() )
699     {
700         case CTRL_SLIDER:
701         {
702             SliderValue* pSlVal = static_cast<SliderValue*>(const_cast<ImplControlValue*>(&rVal));
703             mirror(pSlVal->maThumbRect,pOutDev,bBack);
704         }
705         break;
706         case CTRL_SCROLLBAR:
707         {
708             ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(const_cast<ImplControlValue*>(&rVal));
709             mirror(pScVal->maThumbRect,pOutDev,bBack);
710             mirror(pScVal->maButton1Rect,pOutDev,bBack);
711             mirror(pScVal->maButton2Rect,pOutDev,bBack);
712         }
713         break;
714         case CTRL_SPINBOX:
715         case CTRL_SPINBUTTONS:
716         {
717             SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(const_cast<ImplControlValue*>(&rVal));
718             mirror(pSpVal->maUpperRect,pOutDev,bBack);
719             mirror(pSpVal->maLowerRect,pOutDev,bBack);
720         }
721         break;
722         case CTRL_TOOLBAR:
723         {
724             ToolbarValue* pTVal = static_cast<ToolbarValue*>(const_cast<ImplControlValue*>(&rVal));
725             mirror(pTVal->maGripRect,pOutDev,bBack);
726         }
727         break;
728     }
729 }
730 
731 sal_Bool SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
732                                                 ControlState nState, const ImplControlValue& aValue,
733                                                 const OUString& aCaption, const OutputDevice *pOutDev )
734 {
735 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
736     {
737         Rectangle rgn( rControlRegion );
738         mirror( rgn, pOutDev );
739         mirror( nType, aValue, pOutDev );
740         sal_Bool bRet = drawNativeControl( nType, nPart, rgn, nState, aValue, aCaption );
741         mirror( nType, aValue, pOutDev, true );
742         return bRet;
743     }
744     else
745         return drawNativeControl( nType, nPart, rControlRegion, nState, aValue, aCaption );
746 }
747 
748 sal_Bool SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
749                                                 ControlState nState, const ImplControlValue& aValue,
750                                                 const OUString& aCaption, const OutputDevice *pOutDev )
751 {
752 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
753     {
754         Rectangle rgn( rControlRegion );
755         mirror( rgn, pOutDev );
756         mirror( nType, aValue, pOutDev );
757         sal_Bool bRet = drawNativeControlText( nType, nPart, rgn, nState, aValue, aCaption );
758         mirror( nType, aValue, pOutDev, true );
759         return bRet;
760     }
761     else
762         return drawNativeControlText( nType, nPart, rControlRegion, nState, aValue, aCaption );
763 }
764 
765 sal_Bool SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState,
766                                                 const ImplControlValue& aValue, const OUString& aCaption,
767                                                 Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion, const OutputDevice *pOutDev )
768 {
769 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
770     {
771         Rectangle rgn( rControlRegion );
772         mirror( rgn, pOutDev );
773         mirror( nType, aValue, pOutDev );
774         if( getNativeControlRegion( nType, nPart, rgn, nState, aValue, aCaption,
775                                                 rNativeBoundingRegion, rNativeContentRegion ) )
776         {
777             mirror( rNativeBoundingRegion, pOutDev, true );
778             mirror( rNativeContentRegion, pOutDev, true );
779             mirror( nType, aValue, pOutDev, true );
780             return sal_True;
781         }
782         else
783         {
784             mirror( nType, aValue, pOutDev, true );
785             return sal_False;
786         }
787     }
788     else
789         return getNativeControlRegion( nType, nPart, rControlRegion, nState, aValue, aCaption,
790                                                 rNativeBoundingRegion, rNativeContentRegion );
791 }
792 
793 bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry,
794                                    const SalBitmap& rSourceBitmap,
795                                    const SalBitmap& rAlphaBitmap,
796                                    const OutputDevice *pOutDev )
797 {
798 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
799 	{
800 		SalTwoRect pPosAry2 = rPosAry;
801 		mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev );
802 		return drawAlphaBitmap( pPosAry2, rSourceBitmap, rAlphaBitmap );
803 	}
804 	else
805 		return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap );
806 }
807 
808 bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight,
809                                  sal_uInt8 nTransparency, const OutputDevice *pOutDev )
810 {
811 	if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) )
812 		mirror( nX, nWidth, pOutDev );
813 
814 	return drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
815 }
816 
817 bool SalGraphics::filterText( const String&, String&, xub_StrLen, xub_StrLen&, xub_StrLen&, xub_StrLen& )
818 {
819     return false;
820 }
821 
822 void SalGraphics::AddDevFontSubstitute( OutputDevice* pOutDev,
823                                         const String& rFontName,
824                                         const String& rReplaceFontName,
825                                         sal_uInt16 nFlags )
826 {
827     pOutDev->ImplAddDevFontSubstitute( rFontName, rReplaceFontName, nFlags );
828 }
829 
830