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