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