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_sw.hxx" 30 31 32 #include <hintids.hxx> 33 #include <tools/urlobj.hxx> 34 #include <vcl/print.hxx> 35 #include <vcl/virdev.hxx> 36 #include <vcl/svapp.hxx> 37 #include <svtools/imapobj.hxx> 38 #include <svtools/imap.hxx> 39 #include <svl/urihelper.hxx> 40 #include <svtools/soerr.hxx> 41 #include <sfx2/progress.hxx> 42 #include <sfx2/docfile.hxx> 43 #include <sfx2/printer.hxx> 44 #include <editeng/udlnitem.hxx> 45 #include <editeng/colritem.hxx> 46 #include <svx/xoutbmp.hxx> 47 #include <vcl/window.hxx> 48 #include <fmturl.hxx> 49 #include <fmtsrnd.hxx> 50 #include <frmfmt.hxx> 51 #include <swrect.hxx> 52 #include <fesh.hxx> 53 #include <doc.hxx> 54 #include <flyfrm.hxx> 55 #include <frmtool.hxx> 56 #include <viewopt.hxx> 57 #include <viewimp.hxx> 58 #include <pam.hxx> 59 #include <hints.hxx> 60 #include <rootfrm.hxx> 61 #include <dflyobj.hxx> 62 #include <pagefrm.hxx> 63 #include <notxtfrm.hxx> 64 #include <grfatr.hxx> 65 #include <charatr.hxx> 66 #include <fmtornt.hxx> 67 #include <ndnotxt.hxx> 68 #include <ndgrf.hxx> 69 #include <ndole.hxx> 70 #include <swregion.hxx> 71 #include <poolfmt.hxx> 72 #include <mdiexp.hxx> 73 #include <swwait.hxx> 74 #include <comcore.hrc> 75 #include <accessibilityoptions.hxx> 76 #include <com/sun/star/embed/EmbedMisc.hpp> 77 #include <com/sun/star/embed/EmbedStates.hpp> 78 79 #include <svtools/embedhlp.hxx> 80 #include <svtools/chartprettypainter.hxx> 81 // --> OD 2009-03-05 #i99665# 82 #include <dview.hxx> 83 // <-- 84 85 using namespace com::sun::star; 86 87 #define DEFTEXTSIZE 12 88 89 extern void ClrContourCache( const SdrObject *pObj ); // TxtFly.Cxx 90 91 92 inline sal_Bool GetRealURL( const SwGrfNode& rNd, String& rTxt ) 93 { 94 sal_Bool bRet = rNd.GetFileFilterNms( &rTxt, 0 ); 95 if( bRet ) 96 rTxt = URIHelper::removePassword( rTxt, INetURLObject::WAS_ENCODED, 97 INetURLObject::DECODE_UNAMBIGUOUS); 98 return bRet; 99 } 100 101 void lcl_PaintReplacement( const SwRect &rRect, const String &rText, 102 const ViewShell &rSh, const SwNoTxtFrm *pFrm, 103 sal_Bool bDefect ) 104 { 105 static Font *pFont = 0; 106 if ( !pFont ) 107 { 108 pFont = new Font(); 109 pFont->SetWeight( WEIGHT_BOLD ); 110 pFont->SetStyleName( aEmptyStr ); 111 pFont->SetName( String::CreateFromAscii( 112 RTL_CONSTASCII_STRINGPARAM( "Arial Unicode" ))); 113 pFont->SetFamily( FAMILY_SWISS ); 114 pFont->SetTransparent( sal_True ); 115 } 116 117 Color aCol( COL_RED ); 118 FontUnderline eUnderline = UNDERLINE_NONE; 119 const SwFmtURL &rURL = pFrm->FindFlyFrm()->GetFmt()->GetURL(); 120 if( rURL.GetURL().Len() || rURL.GetMap() ) 121 { 122 sal_Bool bVisited = sal_False; 123 if ( rURL.GetMap() ) 124 { 125 ImageMap *pMap = (ImageMap*)rURL.GetMap(); 126 for( sal_uInt16 i = 0; i < pMap->GetIMapObjectCount(); i++ ) 127 { 128 IMapObject *pObj = pMap->GetIMapObject( i ); 129 if( rSh.GetDoc()->IsVisitedURL( pObj->GetURL() ) ) 130 { 131 bVisited = sal_True; 132 break; 133 } 134 } 135 } 136 else if ( rURL.GetURL().Len() ) 137 bVisited = rSh.GetDoc()->IsVisitedURL( rURL.GetURL() ); 138 139 SwFmt *pFmt = rSh.GetDoc()->GetFmtFromPool( static_cast<sal_uInt16> 140 (bVisited ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL ) ); 141 aCol = pFmt->GetColor().GetValue(); 142 eUnderline = pFmt->GetUnderline().GetLineStyle(); 143 } 144 145 pFont->SetUnderline( eUnderline ); 146 pFont->SetColor( aCol ); 147 148 const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( bDefect != sal_False ); 149 Graphic::DrawEx( rSh.GetOut(), rText, *pFont, rBmp, rRect.Pos(), rRect.SSize() ); 150 } 151 152 /************************************************************************* 153 |* 154 |* SwGrfFrm::SwGrfFrm(ViewShell * const,SwGrfNode *) 155 |* 156 |* Beschreibung 157 |* Ersterstellung JP 05.03.91 158 |* Letzte Aenderung MA 03. Mar. 93 159 |* 160 *************************************************************************/ 161 162 163 SwNoTxtFrm::SwNoTxtFrm(SwNoTxtNode * const pNode, SwFrm* pSib ) 164 : SwCntntFrm( pNode, pSib ) 165 { 166 InitCtor(); 167 } 168 169 // Initialisierung: z.Zt. Eintragen des Frames im Cache 170 171 172 void SwNoTxtFrm::InitCtor() 173 { 174 nType = FRMC_NOTXT; 175 // Das Gewicht der Grafik ist 0, wenn sie noch nicht 176 // gelesen ist, < 0, wenn ein Lesefehler auftrat und 177 // Ersatzdarstellung angewendet werden musste und >0, 178 // wenn sie zur Verfuegung steht. 179 nWeight = 0; 180 } 181 182 /************************************************************************* 183 |* 184 |* SwNoTxtNode::MakeFrm() 185 |* 186 |* Beschreibung 187 |* Ersterstellung JP 05.03.91 188 |* Letzte Aenderung MA 03. Mar. 93 189 |* 190 *************************************************************************/ 191 192 193 SwCntntFrm *SwNoTxtNode::MakeFrm( SwFrm* pSib ) 194 { 195 return new SwNoTxtFrm(this, pSib); 196 } 197 198 /************************************************************************* 199 |* 200 |* SwNoTxtFrm::~SwNoTxtFrm() 201 |* 202 |* Beschreibung 203 |* Ersterstellung JP 05.03.91 204 |* Letzte Aenderung MA 30. Apr. 96 205 |* 206 *************************************************************************/ 207 208 SwNoTxtFrm::~SwNoTxtFrm() 209 { 210 StopAnimation(); 211 } 212 213 /************************************************************************* 214 |* 215 |* void SwNoTxtFrm::Modify( SwHint * pOld, SwHint * pNew ) 216 |* 217 |* Beschreibung 218 |* Ersterstellung JP 05.03.91 219 |* Letzte Aenderung JP 05.03.91 220 |* 221 *************************************************************************/ 222 223 void SetOutDev( ViewShell *pSh, OutputDevice *pOut ) 224 { 225 pSh->pOut = pOut; 226 } 227 228 229 230 231 void lcl_ClearArea( const SwFrm &rFrm, 232 OutputDevice &rOut, const SwRect& rPtArea, 233 const SwRect &rGrfArea ) 234 { 235 SwRegionRects aRegion( rPtArea, 4, 4 ); 236 aRegion -= rGrfArea; 237 238 if ( aRegion.Count() ) 239 { 240 const SvxBrushItem *pItem; const Color *pCol; SwRect aOrigRect; 241 if ( rFrm.GetBackgroundBrush( pItem, pCol, aOrigRect, sal_False ) ) 242 for( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 243 ::DrawGraphic( pItem, &rOut, aOrigRect, aRegion[i] ); 244 else 245 { 246 // OD 2004-04-23 #116347# 247 rOut.Push( PUSH_FILLCOLOR|PUSH_LINECOLOR ); 248 rOut.SetFillColor( rFrm.getRootFrm()->GetCurrShell()->Imp()->GetRetoucheColor()); 249 rOut.SetLineColor(); 250 for( sal_uInt16 i = 0; i < aRegion.Count(); ++i ) 251 rOut.DrawRect( aRegion[i].SVRect() ); 252 rOut.Pop(); 253 } 254 } 255 } 256 257 /************************************************************************* 258 |* 259 |* void SwNoTxtFrm::Paint() 260 |* 261 |* Beschreibung 262 |* Ersterstellung JP 05.03.91 263 |* Letzte Aenderung MA 10. Jan. 97 264 |* 265 *************************************************************************/ 266 267 void SwNoTxtFrm::Paint(SwRect const& rRect, SwPrintData const*const) const 268 { 269 if ( Frm().IsEmpty() ) 270 return; 271 272 const ViewShell* pSh = getRootFrm()->GetCurrShell(); 273 if( !pSh->GetViewOptions()->IsGraphic() ) 274 { 275 StopAnimation(); 276 // OD 10.01.2003 #i6467# - no paint of placeholder for page preview 277 if ( pSh->GetWin() && !pSh->IsPreView() ) 278 { 279 const SwNoTxtNode* pNd = GetNode()->GetNoTxtNode(); 280 String aTxt( pNd->GetTitle() ); 281 if ( !aTxt.Len() && pNd->IsGrfNode() ) 282 GetRealURL( *(SwGrfNode*)pNd, aTxt ); 283 if( !aTxt.Len() ) 284 aTxt = FindFlyFrm()->GetFmt()->GetName(); 285 lcl_PaintReplacement( Frm(), aTxt, *pSh, this, sal_False ); 286 } 287 return; 288 } 289 290 if( pSh->GetAccessibilityOptions()->IsStopAnimatedGraphics() || 291 // --> FME 2004-06-21 #i9684# Stop animation during printing/pdf export 292 !pSh->GetWin() ) 293 // <-- 294 StopAnimation(); 295 296 SfxProgress::EnterLock(); //Keine Progress-Reschedules im Paint (SwapIn) 297 298 OutputDevice *pOut = pSh->GetOut(); 299 pOut->Push(); 300 sal_Bool bClip = sal_True; 301 PolyPolygon aPoly; 302 303 SwNoTxtNode& rNoTNd = *(SwNoTxtNode*)GetNode(); 304 SwGrfNode* pGrfNd = rNoTNd.GetGrfNode(); 305 if( pGrfNd ) 306 pGrfNd->SetFrameInPaint( sal_True ); 307 308 // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True> to 309 // method call <FindFlyFrm().GetContour(..)> to indicate that it is called 310 // for paint in order to avoid load of the intrinsic graphic. 311 if ( ( !pOut->GetConnectMetaFile() || 312 !pSh->GetWin() ) && 313 FindFlyFrm()->GetContour( aPoly, sal_True ) 314 ) 315 { 316 pOut->SetClipRegion( aPoly ); 317 bClip = sal_False; 318 } 319 320 SwRect aOrigPaint( rRect ); 321 if ( HasAnimation() && pSh->GetWin() ) 322 { 323 aOrigPaint = Frm(); aOrigPaint += Prt().Pos(); 324 } 325 326 SwRect aGrfArea( Frm() ); 327 SwRect aPaintArea( aGrfArea ); 328 aPaintArea._Intersection( aOrigPaint ); 329 330 SwRect aNormal( Frm().Pos() + Prt().Pos(), Prt().SSize() ); 331 aNormal.Justify(); //Normalisiertes Rechteck fuer die Vergleiche 332 333 if( aPaintArea.IsOver( aNormal ) ) 334 { 335 // berechne die 4 zu loeschenden Rechtecke 336 if( pSh->GetWin() ) 337 ::lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, aNormal ); 338 339 // in der Schnittmenge vom PaintBereich und der Bitmap liegt 340 // der absolut sichtbare Bereich vom Frame 341 aPaintArea._Intersection( aNormal ); 342 343 if ( bClip ) 344 pOut->IntersectClipRegion( aPaintArea.SVRect() ); 345 /// OD 25.09.2002 #99739# - delete unused 3rd parameter 346 PaintPicture( pOut, aGrfArea ); 347 } 348 else 349 // wenn nicht sichtbar, loesche einfach den angegebenen Bereich 350 lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, SwRect() ); 351 if( pGrfNd ) 352 pGrfNd->SetFrameInPaint( sal_False ); 353 354 pOut->Pop(); 355 SfxProgress::LeaveLock(); 356 } 357 358 /************************************************************************* 359 |* 360 |* void lcl_CalcRect( Point & aPt, Size & aDim, 361 |* sal_uInt16 nMirror ) 362 |* 363 |* Beschreibung Errechne die Position und die Groesse der Grafik im 364 |* Frame, entsprechen der aktuellen Grafik-Attribute 365 |* 366 |* Parameter Point& die Position im Frame ( auch Return-Wert ) 367 |* Size& die Groesse der Grafik ( auch Return-Wert ) 368 |* MirrorGrf akt. Spiegelungs-Attribut 369 |* Ersterstellung JP 04.03.91 370 |* Letzte Aenderung JP 31.08.94 371 |* 372 *************************************************************************/ 373 374 375 void lcl_CalcRect( Point& rPt, Size& rDim, sal_uInt16 nMirror ) 376 { 377 if( nMirror == RES_MIRROR_GRAPH_VERT || nMirror == RES_MIRROR_GRAPH_BOTH ) 378 { 379 rPt.X() += rDim.Width() -1; 380 rDim.Width() = -rDim.Width(); 381 } 382 383 if( nMirror == RES_MIRROR_GRAPH_HOR || nMirror == RES_MIRROR_GRAPH_BOTH ) 384 { 385 rPt.Y() += rDim.Height() -1; 386 rDim.Height() = -rDim.Height(); 387 } 388 } 389 390 /************************************************************************* 391 |* 392 |* void SwNoTxtFrm::GetGrfArea() 393 |* 394 |* Beschreibung Errechne die Position und die Groesse der Bitmap 395 |* innerhalb des uebergebenem Rechtecks. 396 |* 397 |* Ersterstellung JP 03.09.91 398 |* Letzte Aenderung MA 11. Oct. 94 399 |* 400 *************************************************************************/ 401 402 void SwNoTxtFrm::GetGrfArea( SwRect &rRect, SwRect* pOrigRect, 403 sal_Bool ) const 404 { 405 // JP 23.01.2001: currently only used for scaling, cropping and mirroring 406 // the contour of graphics! 407 // all other is handled by the GraphicObject 408 409 //In rRect wird das sichbare Rechteck der Grafik gesteckt. 410 //In pOrigRect werden Pos+Size der Gesamtgrafik gesteck. 411 412 const SwAttrSet& rAttrSet = GetNode()->GetSwAttrSet(); 413 const SwCropGrf& rCrop = rAttrSet.GetCropGrf(); 414 sal_uInt16 nMirror = rAttrSet.GetMirrorGrf().GetValue(); 415 416 if( rAttrSet.GetMirrorGrf().IsGrfToggle() ) 417 { 418 if( !(FindPageFrm()->GetVirtPageNum() % 2) ) 419 { 420 switch ( nMirror ) 421 { 422 case RES_MIRROR_GRAPH_DONT: nMirror = RES_MIRROR_GRAPH_VERT; break; 423 case RES_MIRROR_GRAPH_VERT: nMirror = RES_MIRROR_GRAPH_DONT; break; 424 case RES_MIRROR_GRAPH_HOR: nMirror = RES_MIRROR_GRAPH_BOTH; break; 425 default: nMirror = RES_MIRROR_GRAPH_HOR; break; 426 } 427 } 428 } 429 430 //Grafik wird vom Node eingelesen falls notwendig. Kann aber schiefgehen. 431 long nLeftCrop, nRightCrop, nTopCrop, nBottomCrop; 432 Size aOrigSz( ((SwNoTxtNode*)GetNode())->GetTwipSize() ); 433 if ( !aOrigSz.Width() ) 434 { 435 aOrigSz.Width() = Prt().Width(); 436 nLeftCrop = -rCrop.GetLeft(); 437 nRightCrop = -rCrop.GetRight(); 438 } 439 else 440 { 441 nLeftCrop = Max( aOrigSz.Width() - 442 (rCrop.GetRight() + rCrop.GetLeft()), long(1) ); 443 const double nScale = double(Prt().Width()) / double(nLeftCrop); 444 nLeftCrop = long(nScale * -rCrop.GetLeft() ); 445 nRightCrop = long(nScale * -rCrop.GetRight() ); 446 } 447 448 // crop values have to be mirrored too 449 if( nMirror == RES_MIRROR_GRAPH_VERT || nMirror == RES_MIRROR_GRAPH_BOTH ) 450 { 451 long nTmpCrop = nLeftCrop; 452 nLeftCrop = nRightCrop; 453 nRightCrop= nTmpCrop; 454 } 455 456 if( !aOrigSz.Height() ) 457 { 458 aOrigSz.Height() = Prt().Height(); 459 nTopCrop = -rCrop.GetTop(); 460 nBottomCrop= -rCrop.GetBottom(); 461 } 462 else 463 { 464 nTopCrop = Max( aOrigSz.Height() - (rCrop.GetTop() + rCrop.GetBottom()), long(1) ); 465 const double nScale = double(Prt().Height()) / double(nTopCrop); 466 nTopCrop = long(nScale * -rCrop.GetTop() ); 467 nBottomCrop= long(nScale * -rCrop.GetBottom() ); 468 } 469 470 // crop values have to be mirrored too 471 if( nMirror == RES_MIRROR_GRAPH_HOR || nMirror == RES_MIRROR_GRAPH_BOTH ) 472 { 473 long nTmpCrop = nTopCrop; 474 nTopCrop = nBottomCrop; 475 nBottomCrop= nTmpCrop; 476 } 477 478 Size aVisSz( Prt().SSize() ); 479 Size aGrfSz( aVisSz ); 480 Point aVisPt( Frm().Pos() + Prt().Pos() ); 481 Point aGrfPt( aVisPt ); 482 483 //Erst das 'sichtbare' Rect einstellen. 484 if ( nLeftCrop > 0 ) 485 { 486 aVisPt.X() += nLeftCrop; 487 aVisSz.Width() -= nLeftCrop; 488 } 489 if ( nTopCrop > 0 ) 490 { 491 aVisPt.Y() += nTopCrop; 492 aVisSz.Height() -= nTopCrop; 493 } 494 if ( nRightCrop > 0 ) 495 aVisSz.Width() -= nRightCrop; 496 if ( nBottomCrop > 0 ) 497 aVisSz.Height() -= nBottomCrop; 498 499 rRect.Pos ( aVisPt ); 500 rRect.SSize( aVisSz ); 501 502 //Ggf. Die Gesamtgrafik berechnen 503 if ( pOrigRect ) 504 { 505 Size aTmpSz( aGrfSz ); 506 aGrfPt.X() += nLeftCrop; 507 aTmpSz.Width() -= nLeftCrop + nRightCrop; 508 aGrfPt.Y() += nTopCrop; 509 aTmpSz.Height()-= nTopCrop + nBottomCrop; 510 511 if( RES_MIRROR_GRAPH_DONT != nMirror ) 512 lcl_CalcRect( aGrfPt, aTmpSz, nMirror ); 513 514 pOrigRect->Pos ( aGrfPt ); 515 pOrigRect->SSize( aTmpSz ); 516 } 517 } 518 519 /************************************************************************* 520 |* 521 |* Size SwNoTxtFrm::GetSize() 522 |* 523 |* Beschreibung Gebe die Groesse des umgebenen FLys und 524 |* damit die der Grafik zurueck. 525 |* Ersterstellung JP 04.03.91 526 |* Letzte Aenderung JP 31.08.94 527 |* 528 *************************************************************************/ 529 530 531 const Size& SwNoTxtFrm::GetSize() const 532 { 533 // gebe die Groesse des Frames zurueck 534 const SwFrm *pFly = FindFlyFrm(); 535 if( !pFly ) 536 pFly = this; 537 return pFly->Prt().SSize(); 538 } 539 540 /************************************************************************* 541 |* 542 |* SwNoTxtFrm::MakeAll() 543 |* 544 |* Ersterstellung MA 29. Nov. 96 545 |* Letzte Aenderung MA 29. Nov. 96 546 |* 547 *************************************************************************/ 548 549 550 void SwNoTxtFrm::MakeAll() 551 { 552 SwCntntNotify aNotify( this ); 553 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); 554 const SwBorderAttrs &rAttrs = *aAccess.Get(); 555 556 while ( !bValidPos || !bValidSize || !bValidPrtArea ) 557 { 558 MakePos(); 559 560 if ( !bValidSize ) 561 Frm().Width( GetUpper()->Prt().Width() ); 562 563 MakePrtArea( rAttrs ); 564 565 if ( !bValidSize ) 566 { bValidSize = sal_True; 567 Format(); 568 } 569 } 570 } 571 572 /************************************************************************* 573 |* 574 |* SwNoTxtFrm::Format() 575 |* 576 |* Beschreibung Errechne die Groesse der Bitmap, wenn noetig 577 |* Ersterstellung JP 11.03.91 578 |* Letzte Aenderung MA 13. Mar. 96 579 |* 580 *************************************************************************/ 581 582 583 void SwNoTxtFrm::Format( const SwBorderAttrs * ) 584 { 585 const Size aNewSize( GetSize() ); 586 587 // hat sich die Hoehe geaendert? 588 SwTwips nChgHght = IsVertical() ? 589 (SwTwips)(aNewSize.Width() - Prt().Width()) : 590 (SwTwips)(aNewSize.Height() - Prt().Height()); 591 if( nChgHght > 0) 592 Grow( nChgHght ); 593 else if( nChgHght < 0) 594 Shrink( Min(Prt().Height(), -nChgHght) ); 595 } 596 597 /************************************************************************* 598 |* 599 |* SwNoTxtFrm::GetCharRect() 600 |* 601 |* Beschreibung 602 |* Ersterstellung SS 29-Apr-1991 603 |* Letzte Aenderung MA 10. Oct. 94 604 |* 605 |*************************************************************************/ 606 607 608 sal_Bool SwNoTxtFrm::GetCharRect( SwRect &rRect, const SwPosition& rPos, 609 SwCrsrMoveState *pCMS ) const 610 { 611 if ( &rPos.nNode.GetNode() != (SwNode*)GetNode() ) 612 return sal_False; 613 614 Calc(); 615 SwRect aFrameRect( Frm() ); 616 rRect = aFrameRect; 617 rRect.Pos( Frm().Pos() + Prt().Pos() ); 618 rRect.SSize( Prt().SSize() ); 619 620 rRect.Justify(); 621 622 // liegt die Bitmap ueberhaupt im sichtbaren Berich ? 623 if( !aFrameRect.IsOver( rRect ) ) 624 { 625 // wenn nicht dann steht der Cursor auf dem Frame 626 rRect = aFrameRect; 627 rRect.Width( 1 ); 628 } 629 else 630 rRect._Intersection( aFrameRect ); 631 632 if ( pCMS ) 633 { 634 if ( pCMS->bRealHeight ) 635 { 636 pCMS->aRealHeight.Y() = rRect.Height(); 637 pCMS->aRealHeight.X() = 0; 638 } 639 } 640 641 return sal_True; 642 } 643 644 645 sal_Bool SwNoTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& , 646 SwCrsrMoveState* ) const 647 { 648 SwCntntNode* pCNd = (SwCntntNode*)GetNode(); 649 pPos->nNode = *pCNd; 650 pPos->nContent.Assign( pCNd, 0 ); 651 return sal_True; 652 } 653 654 #define CLEARCACHE( pNd ) {\ 655 (pNd)->GetGrfObj().ReleaseFromCache();\ 656 SwFlyFrm* pFly = FindFlyFrm();\ 657 if( pFly && pFly->GetFmt()->GetSurround().IsContour() )\ 658 {\ 659 ClrContourCache( pFly->GetVirtDrawObj() );\ 660 pFly->NotifyBackground( FindPageFrm(), Prt(), PREP_FLY_ATTR_CHG );\ 661 }\ 662 } 663 664 void SwNoTxtFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) 665 { 666 sal_uInt16 nWhich = pNew ? pNew->Which() : pOld ? pOld->Which() : 0; 667 668 // --> OD 2007-03-06 #i73788# 669 // no <SwCntntFrm::Modify(..)> for RES_LINKED_GRAPHIC_STREAM_ARRIVED 670 if ( RES_GRAPHIC_PIECE_ARRIVED != nWhich && 671 RES_GRAPHIC_ARRIVED != nWhich && 672 RES_GRF_REREAD_AND_INCACHE != nWhich && 673 RES_LINKED_GRAPHIC_STREAM_ARRIVED != nWhich ) 674 // <-- 675 { 676 SwCntntFrm::Modify( pOld, pNew ); 677 } 678 679 sal_Bool bComplete = sal_True; 680 681 switch( nWhich ) 682 { 683 case RES_OBJECTDYING: 684 break; 685 686 case RES_GRF_REREAD_AND_INCACHE: 687 if( ND_GRFNODE == GetNode()->GetNodeType() ) 688 { 689 bComplete = sal_False; 690 SwGrfNode* pNd = (SwGrfNode*) GetNode(); 691 692 ViewShell *pVSh = 0; 693 pNd->GetDoc()->GetEditShell( &pVSh ); 694 if( pVSh ) 695 { 696 GraphicAttr aAttr; 697 if( pNd->GetGrfObj().IsCached( pVSh->GetOut(), Point(), 698 Prt().SSize(), &pNd->GetGraphicAttr( aAttr, this ) )) 699 { 700 ViewShell *pSh = pVSh; 701 do { 702 SET_CURR_SHELL( pSh ); 703 if( pSh->GetWin() ) 704 { 705 if( pSh->IsPreView() ) 706 ::RepaintPagePreview( pSh, Frm().SVRect() ); 707 else 708 pSh->GetWin()->Invalidate( Frm().SVRect() ); 709 } 710 } while( pVSh != (pSh = (ViewShell*)pSh->GetNext() )); 711 } 712 else 713 pNd->SwapIn(); 714 } 715 } 716 break; 717 718 case RES_UPDATE_ATTR: 719 case RES_FMT_CHG: 720 CLEARCACHE( (SwGrfNode*) GetNode() ) 721 break; 722 723 case RES_ATTRSET_CHG: 724 { 725 sal_uInt16 n; 726 for( n = RES_GRFATR_BEGIN; n < RES_GRFATR_END; ++n ) 727 if( SFX_ITEM_SET == ((SwAttrSetChg*)pOld)->GetChgSet()-> 728 GetItemState( n, sal_False )) 729 { 730 CLEARCACHE( (SwGrfNode*) GetNode() ) 731 break; 732 } 733 if( RES_GRFATR_END == n ) // not found 734 return ; 735 } 736 break; 737 738 case RES_GRAPHIC_PIECE_ARRIVED: 739 case RES_GRAPHIC_ARRIVED: 740 // --> OD 2007-03-06 #i73788# 741 // handle RES_LINKED_GRAPHIC_STREAM_ARRIVED as RES_GRAPHIC_ARRIVED 742 case RES_LINKED_GRAPHIC_STREAM_ARRIVED: 743 // <-- 744 if ( GetNode()->GetNodeType() == ND_GRFNODE ) 745 { 746 bComplete = sal_False; 747 SwGrfNode* pNd = (SwGrfNode*) GetNode(); 748 749 CLEARCACHE( pNd ) 750 751 SwRect aRect( Frm() ); 752 753 ViewShell *pVSh = 0; 754 pNd->GetDoc()->GetEditShell( &pVSh ); 755 if( !pVSh ) 756 break; 757 758 ViewShell *pSh = pVSh; 759 do { 760 SET_CURR_SHELL( pSh ); 761 if( pSh->IsPreView() ) 762 { 763 if( pSh->GetWin() ) 764 ::RepaintPagePreview( pSh, aRect ); 765 } 766 else if ( pSh->VisArea().IsOver( aRect ) && 767 OUTDEV_WINDOW == pSh->GetOut()->GetOutDevType() ) 768 { 769 // OD 27.11.2002 #105519# - invalidate instead of painting 770 pSh->GetWin()->Invalidate( aRect.SVRect() ); 771 } 772 773 pSh = (ViewShell *)pSh->GetNext(); 774 } while( pSh != pVSh ); 775 } 776 break; 777 778 default: 779 if ( !pNew || !isGRFATR(nWhich) ) 780 return; 781 } 782 783 if( bComplete ) 784 { 785 InvalidatePrt(); 786 SetCompletePaint(); 787 } 788 } 789 790 void lcl_correctlyAlignRect( SwRect& rAlignedGrfArea, const SwRect& rInArea, OutputDevice* pOut ) 791 { 792 793 if(!pOut) 794 return; 795 Rectangle aPxRect = pOut->LogicToPixel( rInArea.SVRect() ); 796 Rectangle aNewPxRect( aPxRect ); 797 while( aNewPxRect.Left() < aPxRect.Left() ) 798 { 799 rAlignedGrfArea.Left( rAlignedGrfArea.Left()+1 ); 800 aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() ); 801 } 802 while( aNewPxRect.Top() < aPxRect.Top() ) 803 { 804 rAlignedGrfArea.Top( rAlignedGrfArea.Top()+1 ); 805 aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() ); 806 } 807 while( aNewPxRect.Bottom() > aPxRect.Bottom() ) 808 { 809 rAlignedGrfArea.Bottom( rAlignedGrfArea.Bottom()-1 ); 810 aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() ); 811 } 812 while( aNewPxRect.Right() > aPxRect.Right() ) 813 { 814 rAlignedGrfArea.Right( rAlignedGrfArea.Right()-1 ); 815 aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() ); 816 } 817 } 818 819 // Ausgabe der Grafik. Hier wird entweder eine QuickDraw-Bmp oder 820 // eine Grafik vorausgesetzt. Ist nichts davon vorhanden, wird 821 // eine Ersatzdarstellung ausgegeben. 822 /// OD 25.09.2002 #99739# - delete unused 3rd parameter. 823 /// OD 25.09.2002 #99739# - use aligned rectangle for drawing graphic. 824 /// OD 25.09.2002 #99739# - pixel-align coordinations for drawing graphic. 825 void SwNoTxtFrm::PaintPicture( OutputDevice* pOut, const SwRect &rGrfArea ) const 826 { 827 ViewShell* pShell = getRootFrm()->GetCurrShell(); 828 829 SwNoTxtNode& rNoTNd = *(SwNoTxtNode*)GetNode(); 830 SwGrfNode* pGrfNd = rNoTNd.GetGrfNode(); 831 SwOLENode* pOLENd = rNoTNd.GetOLENode(); 832 833 const sal_Bool bPrn = pOut == rNoTNd.getIDocumentDeviceAccess()->getPrinter( false ) || 834 pOut->GetConnectMetaFile(); 835 836 const bool bIsChart = pOLENd && ChartPrettyPainter::IsChart( pOLENd->GetOLEObj().GetObject() ); 837 838 /// OD 25.09.2002 #99739# - calculate aligned rectangle from parameter <rGrfArea>. 839 /// Use aligned rectangle <aAlignedGrfArea> instead of <rGrfArea> in 840 /// the following code. 841 SwRect aAlignedGrfArea = rGrfArea; 842 ::SwAlignRect( aAlignedGrfArea, pShell ); 843 844 if( !bIsChart ) 845 { 846 /// OD 25.09.2002 #99739# 847 /// Because for drawing a graphic left-top-corner and size coordinations are 848 /// used, these coordinations have to be determined on pixel level. 849 ::SwAlignGrfRect( &aAlignedGrfArea, *pOut ); 850 } 851 else //if( bIsChart ) 852 { 853 //#i78025# charts own borders are not completely visible 854 //the above pixel correction is not correct - at least not for charts 855 //so a different pixel correction is choosen here 856 //this might be a good idea for all other OLE objects also, 857 //but as I cannot oversee the consequences I fix it only for charts for now 858 lcl_correctlyAlignRect( aAlignedGrfArea, rGrfArea, pOut ); 859 } 860 861 if( pGrfNd ) 862 { 863 sal_Bool bForceSwap = sal_False, bContinue = sal_True; 864 GraphicObject& rGrfObj = pGrfNd->GetGrfObj(); 865 866 GraphicAttr aGrfAttr; 867 pGrfNd->GetGraphicAttr( aGrfAttr, this ); 868 869 if( !bPrn ) 870 { 871 // --> OD 2007-01-02 #i73788# 872 if ( pGrfNd->IsLinkedInputStreamReady() ) 873 { 874 pGrfNd->UpdateLinkWithInputStream(); 875 } 876 // <-- 877 // --> OD 2008-01-30 #i85717# 878 // --> OD 2008-07-21 #i90395# - check, if asynchronous retrieval 879 // if input stream for the graphic is possible 880 // else if( GRAPHIC_DEFAULT == rGrfObj.GetType() && 881 else if ( ( rGrfObj.GetType() == GRAPHIC_DEFAULT || 882 rGrfObj.GetType() == GRAPHIC_NONE ) && 883 pGrfNd->IsLinkedFile() && 884 pGrfNd->IsAsyncRetrieveInputStreamPossible() ) 885 // <-- 886 { 887 Size aTmpSz; 888 ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj(); 889 if( !pGrfObj || 890 !pGrfObj->IsDataComplete() || 891 !(aTmpSz = pGrfNd->GetTwipSize()).Width() || 892 !aTmpSz.Height() || !pGrfNd->GetAutoFmtLvl() ) 893 { 894 // --> OD 2006-12-22 #i73788# 895 pGrfNd->TriggerAsyncRetrieveInputStream(); 896 // <-- 897 } 898 String aTxt( pGrfNd->GetTitle() ); 899 if ( !aTxt.Len() ) 900 GetRealURL( *pGrfNd, aTxt ); 901 ::lcl_PaintReplacement( aAlignedGrfArea, aTxt, *pShell, this, sal_False ); 902 bContinue = sal_False; 903 } 904 else if( rGrfObj.IsCached( pOut, aAlignedGrfArea.Pos(), 905 aAlignedGrfArea.SSize(), &aGrfAttr )) 906 { 907 rGrfObj.DrawWithPDFHandling( *pOut, 908 aAlignedGrfArea.Pos(), aAlignedGrfArea.SSize(), 909 &aGrfAttr ); 910 bContinue = sal_False; 911 } 912 } 913 914 if( bContinue ) 915 { 916 const sal_Bool bSwapped = rGrfObj.IsSwappedOut(); 917 const sal_Bool bSwappedIn = 0 != pGrfNd->SwapIn( bPrn ); 918 if( bSwappedIn && rGrfObj.GetGraphic().IsSupportedGraphic()) 919 { 920 const sal_Bool bAnimate = rGrfObj.IsAnimated() && 921 !pShell->IsPreView() && 922 !pShell->GetAccessibilityOptions()->IsStopAnimatedGraphics() && 923 // --> FME 2004-06-21 #i9684# Stop animation during printing/pdf export 924 pShell->GetWin(); 925 // <-- 926 927 if( bAnimate && 928 FindFlyFrm() != ::GetFlyFromMarked( 0, pShell )) 929 { 930 OutputDevice* pVout; 931 if( pOut == pShell->GetOut() && SwRootFrm::FlushVout() ) 932 pVout = pOut, pOut = pShell->GetOut(); 933 else if( pShell->GetWin() && 934 OUTDEV_VIRDEV == pOut->GetOutDevType() ) 935 pVout = pOut, pOut = pShell->GetWin(); 936 else 937 pVout = 0; 938 939 ASSERT( OUTDEV_VIRDEV != pOut->GetOutDevType() || 940 pShell->GetViewOptions()->IsPDFExport(), 941 "pOut sollte kein virtuelles Device sein" ); 942 943 rGrfObj.StartAnimation( pOut, aAlignedGrfArea.Pos(), 944 aAlignedGrfArea.SSize(), long(this), 945 0, GRFMGR_DRAW_STANDARD, pVout ); 946 } 947 else 948 rGrfObj.DrawWithPDFHandling( *pOut, 949 aAlignedGrfArea.Pos(), aAlignedGrfArea.SSize(), 950 &aGrfAttr ); 951 } 952 else 953 { 954 sal_uInt16 nResId = 0; 955 if( bSwappedIn ) 956 { 957 if( GRAPHIC_NONE == rGrfObj.GetType() ) 958 nResId = STR_COMCORE_READERROR; 959 else if ( !rGrfObj.GetGraphic().IsSupportedGraphic() ) 960 nResId = STR_COMCORE_CANT_SHOW; 961 } 962 ((SwNoTxtFrm*)this)->nWeight = -1; 963 String aText; 964 if ( !nResId && 965 !(aText = pGrfNd->GetTitle()).Len() && 966 (!GetRealURL( *pGrfNd, aText ) || !aText.Len())) 967 { 968 nResId = STR_COMCORE_READERROR; 969 } 970 if ( nResId ) 971 aText = SW_RESSTR( nResId ); 972 973 ::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, sal_True ); 974 } 975 976 //Beim Drucken duerfen wir nicht die Grafiken sammeln... 977 if( bSwapped && bPrn ) 978 bForceSwap = sal_True; 979 } 980 if( bForceSwap ) 981 pGrfNd->SwapOut(); 982 } 983 else if( bIsChart 984 //charts must be painted resolution dependent!! #i82893#, #i75867# 985 && ChartPrettyPainter::ShouldPrettyPaintChartOnThisDevice( pOut ) 986 && svt::EmbeddedObjectRef::TryRunningState( pOLENd->GetOLEObj().GetOleRef() ) 987 && ChartPrettyPainter::DoPrettyPaintChart( uno::Reference< frame::XModel >( 988 pOLENd->GetOLEObj().GetOleRef()->getComponent(), uno::UNO_QUERY), pOut, aAlignedGrfArea.SVRect() ) ) 989 { 990 (void)(0);//all was done in if statement 991 } 992 else if( pOLENd ) 993 { 994 // --> OD 2009-03-05 #i99665# 995 // Adjust AntiAliasing mode at output device for chart OLE 996 const sal_uInt16 nFormerAntialiasingAtOutput( pOut->GetAntialiasing() ); 997 if ( pOLENd->IsChart() && 998 pShell->Imp()->GetDrawView()->IsAntiAliasing() ) 999 { 1000 const sal_uInt16 nAntialiasingForChartOLE = 1001 nFormerAntialiasingAtOutput | ANTIALIASING_PIXELSNAPHAIRLINE; 1002 pOut->SetAntialiasing( nAntialiasingForChartOLE ); 1003 } 1004 // <-- 1005 1006 Point aPosition(aAlignedGrfArea.Pos()); 1007 Size aSize(aAlignedGrfArea.SSize()); 1008 1009 // Im BrowseModus gibt es nicht unbedingt einen Drucker und 1010 // damit kein JobSetup, also legen wir eines an ... 1011 const JobSetup* pJobSetup = pOLENd->getIDocumentDeviceAccess()->getJobsetup(); 1012 sal_Bool bDummyJobSetup = 0 == pJobSetup; 1013 if( bDummyJobSetup ) 1014 pJobSetup = new JobSetup(); 1015 1016 // #i42323# 1017 // The reason for #114233# is gone, so i remove it again 1018 //TODO/LATER: is it a problem that the JopSetup isn't used? 1019 //xRef->DoDraw( pOut, aAlignedGrfArea.Pos(), aAlignedGrfArea.SSize(), *pJobSetup ); 1020 1021 // get hi-contrast image, but never for printing 1022 Graphic* pGraphic = NULL; 1023 if (pOut && !bPrn && Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) 1024 pGraphic = pOLENd->GetHCGraphic(); 1025 1026 // when it is not possible to get HC-representation, the original image should be used 1027 if ( !pGraphic ) 1028 pGraphic = pOLENd->GetGraphic(); 1029 1030 if ( pGraphic && pGraphic->GetType() != GRAPHIC_NONE ) 1031 { 1032 pGraphic->Draw( pOut, aPosition, aSize ); 1033 1034 // shade the representation if the object is activated outplace 1035 uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef(); 1036 if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::ACTIVE ) 1037 { 1038 ::svt::EmbeddedObjectRef::DrawShading( Rectangle( aPosition, aSize ), pOut ); 1039 } 1040 } 1041 else 1042 ::svt::EmbeddedObjectRef::DrawPaintReplacement( Rectangle( aPosition, aSize ), pOLENd->GetOLEObj().GetCurrentPersistName(), pOut ); 1043 1044 if( bDummyJobSetup ) 1045 delete pJobSetup; // ... und raeumen wieder auf. 1046 1047 sal_Int64 nMiscStatus = pOLENd->GetOLEObj().GetOleRef()->getStatus( pOLENd->GetAspect() ); 1048 if ( !bPrn && pShell->ISA( SwCrsrShell ) && 1049 nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE ) 1050 { 1051 const SwFlyFrm *pFly = FindFlyFrm(); 1052 ASSERT( pFly, "OLE not in FlyFrm" ); 1053 ((SwFEShell*)pShell)->ConnectObj( pOLENd->GetOLEObj().GetObject(), pFly->Prt(), pFly->Frm()); 1054 } 1055 1056 // --> OD 2009-03-05 #i99665# 1057 if ( pOLENd->IsChart() && 1058 pShell->Imp()->GetDrawView()->IsAntiAliasing() ) 1059 { 1060 pOut->SetAntialiasing( nFormerAntialiasingAtOutput ); 1061 } 1062 // <-- 1063 } 1064 } 1065 1066 1067 sal_Bool SwNoTxtFrm::IsTransparent() const 1068 { 1069 const ViewShell* pSh = getRootFrm()->GetCurrShell(); 1070 if ( !pSh || !pSh->GetViewOptions()->IsGraphic() ) 1071 return sal_True; 1072 1073 const SwGrfNode *pNd; 1074 if( 0 != (pNd = GetNode()->GetGrfNode()) ) 1075 return pNd->IsTransparent(); 1076 1077 //#29381# OLE sind immer Transparent. 1078 return sal_True; 1079 } 1080 1081 1082 void SwNoTxtFrm::StopAnimation( OutputDevice* pOut ) const 1083 { 1084 //animierte Grafiken anhalten 1085 SwGrfNode* pGrfNd = (SwGrfNode*)GetNode()->GetGrfNode(); 1086 if( pGrfNd && pGrfNd->IsAnimated() ) 1087 pGrfNd->GetGrfObj().StopAnimation( pOut, long(this) ); 1088 } 1089 1090 1091 sal_Bool SwNoTxtFrm::HasAnimation() const 1092 { 1093 const SwGrfNode* pGrfNd = GetNode()->GetGrfNode(); 1094 return pGrfNd && pGrfNd->IsAnimated(); 1095 } 1096 1097 1098 1099