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