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