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