Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <tools/urlobj.hxx>
22 : #include <vcl/print.hxx>
23 : #include <vcl/virdev.hxx>
24 : #include <vcl/svapp.hxx>
25 : #include <svtools/imapobj.hxx>
26 : #include <svtools/imap.hxx>
27 : #include <svl/urihelper.hxx>
28 : #include <svtools/soerr.hxx>
29 : #include <sfx2/progress.hxx>
30 : #include <sfx2/docfile.hxx>
31 : #include <sfx2/printer.hxx>
32 : #include <editeng/udlnitem.hxx>
33 : #include <editeng/colritem.hxx>
34 : #include <svx/xoutbmp.hxx>
35 : #include <vcl/window.hxx>
36 : #include <fmturl.hxx>
37 : #include <fmtsrnd.hxx>
38 : #include <frmfmt.hxx>
39 : #include <swrect.hxx>
40 : #include <fesh.hxx>
41 : #include <doc.hxx>
42 : #include <IDocumentSettingAccess.hxx>
43 : #include <IDocumentStylePoolAccess.hxx>
44 : #include <IDocumentDeviceAccess.hxx>
45 : #include <IDocumentLayoutAccess.hxx>
46 : #include <flyfrm.hxx>
47 : #include <flyfrms.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 <drawinglayer/primitive2d/graphicprimitive2d.hxx>
77 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
78 : #include <drawinglayer/processor2d/processor2dtools.hxx>
79 : #include <txtfly.hxx>
80 : #include <vcl/graphicfilter.hxx>
81 : #include <vcl/pdfextoutdevdata.hxx>
82 :
83 : using namespace com::sun::star;
84 :
85 5 : inline bool GetRealURL( const SwGrfNode& rNd, OUString& rText )
86 : {
87 5 : bool bRet = rNd.GetFileFilterNms( &rText, 0 );
88 5 : if( bRet )
89 10 : rText = URIHelper::removePassword( rText, INetURLObject::WAS_ENCODED,
90 5 : INetURLObject::DECODE_UNAMBIGUOUS);
91 5 : if (rText.startsWith("data:image")) rText = "inline image";
92 :
93 5 : return bRet;
94 : }
95 :
96 13 : static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText,
97 : const SwViewShell &rSh, const SwNoTextFrm *pFrm,
98 : bool bDefect )
99 : {
100 : static vcl::Font *pFont = 0;
101 13 : if ( !pFont )
102 : {
103 3 : pFont = new vcl::Font();
104 3 : pFont->SetWeight( WEIGHT_BOLD );
105 3 : pFont->SetStyleName( OUString() );
106 3 : pFont->SetName(OUString("Arial Unicode"));
107 3 : pFont->SetFamily( FAMILY_SWISS );
108 3 : pFont->SetTransparent( true );
109 : }
110 :
111 13 : Color aCol( COL_RED );
112 13 : FontUnderline eUnderline = UNDERLINE_NONE;
113 13 : const SwFormatURL &rURL = pFrm->FindFlyFrm()->GetFormat()->GetURL();
114 13 : if( !rURL.GetURL().isEmpty() || rURL.GetMap() )
115 : {
116 0 : bool bVisited = false;
117 0 : if ( rURL.GetMap() )
118 : {
119 0 : ImageMap *pMap = const_cast<ImageMap*>(rURL.GetMap());
120 0 : for( size_t i = 0; i < pMap->GetIMapObjectCount(); ++i )
121 : {
122 0 : IMapObject *pObj = pMap->GetIMapObject( i );
123 0 : if( rSh.GetDoc()->IsVisitedURL( pObj->GetURL() ) )
124 : {
125 0 : bVisited = true;
126 0 : break;
127 : }
128 : }
129 : }
130 0 : else if ( !rURL.GetURL().isEmpty() )
131 0 : bVisited = rSh.GetDoc()->IsVisitedURL( rURL.GetURL() );
132 :
133 0 : SwFormat *pFormat = rSh.GetDoc()->getIDocumentStylePoolAccess().GetFormatFromPool( static_cast<sal_uInt16>
134 0 : (bVisited ? RES_POOLCHR_INET_VISIT : RES_POOLCHR_INET_NORMAL ) );
135 0 : aCol = pFormat->GetColor().GetValue();
136 0 : eUnderline = pFormat->GetUnderline().GetLineStyle();
137 : }
138 :
139 13 : pFont->SetUnderline( eUnderline );
140 13 : pFont->SetColor( aCol );
141 :
142 13 : const BitmapEx& rBmp = SwViewShell::GetReplacementBitmap( bDefect );
143 13 : Graphic::DrawEx( rSh.GetOut(), rText, *pFont, rBmp, rRect.Pos(), rRect.SSize() );
144 13 : }
145 :
146 1029 : SwNoTextFrm::SwNoTextFrm(SwNoTextNode * const pNode, SwFrm* pSib )
147 1029 : : SwContentFrm( pNode, pSib )
148 : {
149 1029 : InitCtor();
150 1029 : }
151 :
152 : /// Initialization: Currently add the Frame to the Cache
153 1029 : void SwNoTextFrm::InitCtor()
154 : {
155 1029 : mnFrmType = FRM_NOTXT;
156 1029 : }
157 :
158 1029 : SwContentFrm *SwNoTextNode::MakeFrm( SwFrm* pSib )
159 : {
160 1029 : return new SwNoTextFrm(this, pSib);
161 : }
162 :
163 1029 : void SwNoTextFrm::DestroyImpl()
164 : {
165 1029 : StopAnimation();
166 :
167 1029 : SwContentFrm::DestroyImpl();
168 1029 : }
169 :
170 2058 : SwNoTextFrm::~SwNoTextFrm()
171 : {
172 2058 : }
173 :
174 0 : void SetOutDev( SwViewShell *pSh, OutputDevice *pOut )
175 : {
176 0 : pSh->mpOut = pOut;
177 0 : }
178 :
179 131 : static void lcl_ClearArea( const SwFrm &rFrm,
180 : vcl::RenderContext &rOut, const SwRect& rPtArea,
181 : const SwRect &rGrfArea )
182 : {
183 131 : SwRegionRects aRegion( rPtArea, 4 );
184 131 : aRegion -= rGrfArea;
185 :
186 131 : if ( !aRegion.empty() )
187 : {
188 0 : const SvxBrushItem *pItem; const Color *pCol; SwRect aOrigRect;
189 :
190 : //UUUU
191 0 : drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes;
192 :
193 0 : if ( rFrm.GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigRect, false ) )
194 : {
195 0 : SwRegionRects const region(rPtArea);
196 0 : const bool bDone(::DrawFillAttributes(aFillAttributes, aOrigRect, region, rOut));
197 :
198 0 : if(!bDone)
199 : {
200 0 : for( const auto &rRegion : aRegion )
201 : {
202 0 : ::DrawGraphic( pItem, &rOut, aOrigRect, rRegion );
203 : }
204 0 : }
205 : }
206 : else
207 : {
208 0 : rOut.Push( PushFlags::FILLCOLOR|PushFlags::LINECOLOR );
209 0 : rOut.SetFillColor( rFrm.getRootFrm()->GetCurrShell()->Imp()->GetRetoucheColor());
210 0 : rOut.SetLineColor();
211 0 : for( const auto &rRegion : aRegion )
212 0 : rOut.DrawRect( rRegion.SVRect() );
213 0 : rOut.Pop();
214 0 : }
215 131 : }
216 131 : }
217 :
218 146 : void SwNoTextFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
219 : {
220 146 : if ( Frm().IsEmpty() )
221 0 : return;
222 :
223 146 : const SwViewShell* pSh = getRootFrm()->GetCurrShell();
224 146 : if( !pSh->GetViewOptions()->IsGraphic() )
225 : {
226 0 : StopAnimation();
227 : // #i6467# - no paint of placeholder for page preview
228 0 : if ( pSh->GetWin() && !pSh->IsPreview() )
229 : {
230 0 : const SwNoTextNode* pNd = GetNode()->GetNoTextNode();
231 0 : OUString aText( pNd->GetTitle() );
232 0 : if ( aText.isEmpty() && pNd->IsGrfNode() )
233 0 : GetRealURL( *static_cast<const SwGrfNode*>(pNd), aText );
234 0 : if( aText.isEmpty() )
235 0 : aText = FindFlyFrm()->GetFormat()->GetName();
236 0 : lcl_PaintReplacement( Frm(), aText, *pSh, this, false );
237 : }
238 0 : return;
239 : }
240 :
241 292 : if( pSh->GetAccessibilityOptions()->IsStopAnimatedGraphics() ||
242 : // #i9684# Stop animation during printing/pdf export
243 146 : !pSh->GetWin() )
244 15 : StopAnimation();
245 :
246 146 : SfxProgress::EnterLock(); // No progress reschedules in paint (SwapIn)
247 :
248 146 : OutputDevice *pOut = pSh->GetOut();
249 146 : pOut->Push();
250 146 : bool bClip = true;
251 146 : tools::PolyPolygon aPoly;
252 :
253 146 : SwNoTextNode& rNoTNd = const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>(GetNode()));
254 146 : SwGrfNode* pGrfNd = rNoTNd.GetGrfNode();
255 146 : if( pGrfNd )
256 101 : pGrfNd->SetFrameInPaint( true );
257 :
258 : // #i13147# - add 2nd parameter with value <true> to
259 : // method call <FindFlyFrm().GetContour(..)> to indicate that it is called
260 : // for paint in order to avoid load of the intrinsic graphic.
261 307 : if ( ( !pOut->GetConnectMetaFile() ||
262 292 : !pSh->GetWin() ) &&
263 146 : FindFlyFrm()->GetContour( aPoly, true )
264 : )
265 : {
266 0 : pOut->SetClipRegion(vcl::Region(aPoly));
267 0 : bClip = false;
268 : }
269 :
270 146 : SwRect aOrigPaint( rRect );
271 146 : if ( HasAnimation() && pSh->GetWin() )
272 : {
273 0 : aOrigPaint = Frm(); aOrigPaint += Prt().Pos();
274 : }
275 :
276 146 : SwRect aGrfArea( Frm() );
277 146 : SwRect aPaintArea( aGrfArea );
278 :
279 : // In case the picture fly frm was clipped, render it with the origin
280 : // size instead of scaling it
281 146 : if ( rNoTNd.getIDocumentSettingAccess()->get( DocumentSettingId::CLIPPED_PICTURES ) )
282 : {
283 76 : const SwFlyFreeFrm *pFly = dynamic_cast< const SwFlyFreeFrm* >( FindFlyFrm() );
284 76 : if( pFly )
285 9 : aGrfArea = SwRect( Frm().Pos( ), pFly->GetUnclippedFrm( ).SSize( ) );
286 : }
287 :
288 146 : aPaintArea._Intersection( aOrigPaint );
289 :
290 146 : SwRect aNormal( Frm().Pos() + Prt().Pos(), Prt().SSize() );
291 146 : aNormal.Justify(); // Normalized rectangle for the comparisons
292 :
293 146 : if( aPaintArea.IsOver( aNormal ) )
294 : {
295 : // Calculate the four to-be-deleted rectangles
296 146 : if( pSh->GetWin() )
297 131 : ::lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, aNormal );
298 :
299 : // The intersection of the PaintArea and the Bitmap contains the absolutely visible area of the Frame
300 146 : aPaintArea._Intersection( aNormal );
301 :
302 146 : if ( bClip )
303 146 : pOut->IntersectClipRegion( aPaintArea.SVRect() );
304 : /// delete unused 3rd parameter
305 146 : PaintPicture( pOut, aGrfArea );
306 : }
307 : else
308 : // If it's not visible, simply delete the given Area
309 0 : lcl_ClearArea( *this, *pSh->GetOut(), aPaintArea, SwRect() );
310 146 : if( pGrfNd )
311 101 : pGrfNd->SetFrameInPaint( false );
312 :
313 146 : pOut->Pop();
314 146 : SfxProgress::LeaveLock();
315 : }
316 :
317 : /** Calculate the position and the size of the graphic in the Frame,
318 : corresponding to the current graphic attributes
319 :
320 : @param Point the position in the Frame (also returned)
321 : @param Size the graphic's size (also returned)
322 : @param nMirror the current mirror attribute
323 : */
324 0 : static void lcl_CalcRect( Point& rPt, Size& rDim, sal_uInt16 nMirror )
325 : {
326 0 : if( nMirror == RES_MIRROR_GRAPH_VERT || nMirror == RES_MIRROR_GRAPH_BOTH )
327 : {
328 0 : rPt.setX(rPt.getX() + rDim.Width() -1);
329 0 : rDim.Width() = -rDim.Width();
330 : }
331 :
332 0 : if( nMirror == RES_MIRROR_GRAPH_HOR || nMirror == RES_MIRROR_GRAPH_BOTH )
333 : {
334 0 : rPt.setY(rPt.getY() + rDim.Height() -1);
335 0 : rDim.Height() = -rDim.Height();
336 : }
337 0 : }
338 :
339 : /** Calculate the Bitmap's position and the size within the passed rectangle */
340 6 : void SwNoTextFrm::GetGrfArea( SwRect &rRect, SwRect* pOrigRect,
341 : bool ) const
342 : {
343 : // Currently only used for scaling, cropping and mirroring the contour of graphics!
344 : // Everything else is handled by GraphicObject
345 :
346 : // We put the graphic's visible rectangle into rRect.
347 : // pOrigRect contains position and size of the whole graphic.
348 :
349 6 : const SwAttrSet& rAttrSet = GetNode()->GetSwAttrSet();
350 6 : const SwCropGrf& rCrop = rAttrSet.GetCropGrf();
351 6 : sal_uInt16 nMirror = rAttrSet.GetMirrorGrf().GetValue();
352 :
353 6 : if( rAttrSet.GetMirrorGrf().IsGrfToggle() )
354 : {
355 0 : if( !(FindPageFrm()->GetVirtPageNum() % 2) )
356 : {
357 0 : switch ( nMirror )
358 : {
359 0 : case RES_MIRROR_GRAPH_DONT: nMirror = RES_MIRROR_GRAPH_VERT; break;
360 0 : case RES_MIRROR_GRAPH_VERT: nMirror = RES_MIRROR_GRAPH_DONT; break;
361 0 : case RES_MIRROR_GRAPH_HOR: nMirror = RES_MIRROR_GRAPH_BOTH; break;
362 0 : default: nMirror = RES_MIRROR_GRAPH_HOR; break;
363 : }
364 : }
365 : }
366 :
367 : // We read graphic from the Node, if needed.
368 : // It may fail, however.
369 : long nLeftCrop, nRightCrop, nTopCrop, nBottomCrop;
370 6 : Size aOrigSz( static_cast<const SwNoTextNode*>(GetNode())->GetTwipSize() );
371 6 : if ( !aOrigSz.Width() )
372 : {
373 0 : aOrigSz.Width() = Prt().Width();
374 0 : nLeftCrop = -rCrop.GetLeft();
375 0 : nRightCrop = -rCrop.GetRight();
376 : }
377 : else
378 : {
379 12 : nLeftCrop = std::max( aOrigSz.Width() -
380 18 : (rCrop.GetRight() + rCrop.GetLeft()), long(1) );
381 6 : const double nScale = double(Prt().Width()) / double(nLeftCrop);
382 6 : nLeftCrop = long(nScale * -rCrop.GetLeft() );
383 6 : nRightCrop = long(nScale * -rCrop.GetRight() );
384 : }
385 :
386 : // crop values have to be mirrored too
387 6 : if( nMirror == RES_MIRROR_GRAPH_VERT || nMirror == RES_MIRROR_GRAPH_BOTH )
388 : {
389 0 : long nTmpCrop = nLeftCrop;
390 0 : nLeftCrop = nRightCrop;
391 0 : nRightCrop= nTmpCrop;
392 : }
393 :
394 6 : if( !aOrigSz.Height() )
395 : {
396 0 : aOrigSz.Height() = Prt().Height();
397 0 : nTopCrop = -rCrop.GetTop();
398 0 : nBottomCrop= -rCrop.GetBottom();
399 : }
400 : else
401 : {
402 6 : nTopCrop = std::max( aOrigSz.Height() - (rCrop.GetTop() + rCrop.GetBottom()), long(1) );
403 6 : const double nScale = double(Prt().Height()) / double(nTopCrop);
404 6 : nTopCrop = long(nScale * -rCrop.GetTop() );
405 6 : nBottomCrop= long(nScale * -rCrop.GetBottom() );
406 : }
407 :
408 : // crop values have to be mirrored too
409 6 : if( nMirror == RES_MIRROR_GRAPH_HOR || nMirror == RES_MIRROR_GRAPH_BOTH )
410 : {
411 0 : long nTmpCrop = nTopCrop;
412 0 : nTopCrop = nBottomCrop;
413 0 : nBottomCrop= nTmpCrop;
414 : }
415 :
416 6 : Size aVisSz( Prt().SSize() );
417 6 : Size aGrfSz( aVisSz );
418 6 : Point aVisPt( Frm().Pos() + Prt().Pos() );
419 6 : Point aGrfPt( aVisPt );
420 :
421 : // Set the "visible" rectangle first
422 6 : if ( nLeftCrop > 0 )
423 : {
424 0 : aVisPt.setX(aVisPt.getX() + nLeftCrop);
425 0 : aVisSz.Width() -= nLeftCrop;
426 : }
427 6 : if ( nTopCrop > 0 )
428 : {
429 0 : aVisPt.setY(aVisPt.getY() + nTopCrop);
430 0 : aVisSz.Height() -= nTopCrop;
431 : }
432 6 : if ( nRightCrop > 0 )
433 0 : aVisSz.Width() -= nRightCrop;
434 6 : if ( nBottomCrop > 0 )
435 0 : aVisSz.Height() -= nBottomCrop;
436 :
437 6 : rRect.Pos ( aVisPt );
438 6 : rRect.SSize( aVisSz );
439 :
440 : // Calculate the whole graphic if needed
441 6 : if ( pOrigRect )
442 : {
443 6 : Size aTmpSz( aGrfSz );
444 6 : aGrfPt.setX(aGrfPt.getX() + nLeftCrop);
445 6 : aTmpSz.Width() -= nLeftCrop + nRightCrop;
446 6 : aGrfPt.setY(aGrfPt.getY() + nTopCrop);
447 6 : aTmpSz.Height()-= nTopCrop + nBottomCrop;
448 :
449 6 : if( RES_MIRROR_GRAPH_DONT != nMirror )
450 0 : lcl_CalcRect( aGrfPt, aTmpSz, nMirror );
451 :
452 6 : pOrigRect->Pos ( aGrfPt );
453 6 : pOrigRect->SSize( aTmpSz );
454 : }
455 6 : }
456 :
457 : /** By returning the surrounding Fly's size which equals the graphic's size */
458 963 : const Size& SwNoTextFrm::GetSize() const
459 : {
460 : // Return the Frame's size
461 963 : const SwFrm *pFly = FindFlyFrm();
462 963 : if( !pFly )
463 0 : pFly = this;
464 963 : return pFly->Prt().SSize();
465 : }
466 :
467 1818 : void SwNoTextFrm::MakeAll()
468 : {
469 1818 : SwContentNotify aNotify( this );
470 3636 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
471 1818 : const SwBorderAttrs &rAttrs = *aAccess.Get();
472 :
473 5454 : while ( !mbValidPos || !mbValidSize || !mbValidPrtArea )
474 : {
475 1818 : MakePos();
476 :
477 1818 : if ( !mbValidSize )
478 963 : Frm().Width( GetUpper()->Prt().Width() );
479 :
480 1818 : MakePrtArea( rAttrs );
481 :
482 1818 : if ( !mbValidSize )
483 963 : { mbValidSize = true;
484 963 : Format();
485 : }
486 1818 : }
487 1818 : }
488 :
489 : /** Calculate the Bitmap's site, if needed */
490 963 : void SwNoTextFrm::Format( const SwBorderAttrs * )
491 : {
492 963 : const Size aNewSize( GetSize() );
493 :
494 : // Did the height change?
495 963 : SwTwips nChgHght = IsVertical() ?
496 0 : (SwTwips)(aNewSize.Width() - Prt().Width()) :
497 963 : (SwTwips)(aNewSize.Height() - Prt().Height());
498 963 : if( nChgHght > 0)
499 962 : Grow( nChgHght );
500 1 : else if( nChgHght < 0)
501 0 : Shrink( std::min(Prt().Height(), -nChgHght) );
502 963 : }
503 :
504 0 : bool SwNoTextFrm::GetCharRect( SwRect &rRect, const SwPosition& rPos,
505 : SwCrsrMoveState *pCMS ) const
506 : {
507 0 : if ( &rPos.nNode.GetNode() != static_cast<SwNode const *>(GetNode()) )
508 0 : return false;
509 :
510 0 : Calc();
511 0 : SwRect aFrameRect( Frm() );
512 0 : rRect = aFrameRect;
513 0 : rRect.Pos( Frm().Pos() + Prt().Pos() );
514 0 : rRect.SSize( Prt().SSize() );
515 :
516 0 : rRect.Justify();
517 :
518 : // Is the Bitmap in the visible area at all?
519 0 : if( !aFrameRect.IsOver( rRect ) )
520 : {
521 : // If not, then the Cursor is on the Frame
522 0 : rRect = aFrameRect;
523 0 : rRect.Width( 1 );
524 : }
525 : else
526 0 : rRect._Intersection( aFrameRect );
527 :
528 0 : if ( pCMS )
529 : {
530 0 : if ( pCMS->bRealHeight )
531 : {
532 0 : pCMS->aRealHeight.setY(rRect.Height());
533 0 : pCMS->aRealHeight.setX(0);
534 : }
535 : }
536 :
537 0 : return true;
538 : }
539 :
540 0 : bool SwNoTextFrm::GetCrsrOfst(SwPosition* pPos, Point& ,
541 : SwCrsrMoveState*, bool ) const
542 : {
543 0 : SwContentNode* pCNd = const_cast<SwContentNode*>(GetNode());
544 0 : pPos->nNode = *pCNd;
545 0 : pPos->nContent.Assign( pCNd, 0 );
546 0 : return true;
547 : }
548 :
549 : #define CLEARCACHE {\
550 : SwFlyFrm* pFly = FindFlyFrm();\
551 : if( pFly && pFly->GetFormat()->GetSurround().IsContour() )\
552 : {\
553 : ClrContourCache( pFly->GetVirtDrawObj() );\
554 : pFly->NotifyBackground( FindPageFrm(), Prt(), PREP_FLY_ATTR_CHG );\
555 : }\
556 : }
557 :
558 149 : void SwNoTextFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
559 : {
560 149 : sal_uInt16 nWhich = pNew ? pNew->Which() : pOld ? pOld->Which() : 0;
561 :
562 : // #i73788#
563 : // no <SwContentFrm::Modify(..)> for RES_LINKED_GRAPHIC_STREAM_ARRIVED
564 149 : if ( RES_GRAPHIC_PIECE_ARRIVED != nWhich &&
565 134 : RES_GRAPHIC_ARRIVED != nWhich &&
566 134 : RES_GRF_REREAD_AND_INCACHE != nWhich &&
567 : RES_LINKED_GRAPHIC_STREAM_ARRIVED != nWhich )
568 : {
569 134 : SwContentFrm::Modify( pOld, pNew );
570 : }
571 :
572 149 : bool bComplete = true;
573 :
574 149 : switch( nWhich )
575 : {
576 : case RES_OBJECTDYING:
577 0 : break;
578 :
579 : case RES_GRF_REREAD_AND_INCACHE:
580 0 : if( ND_GRFNODE == GetNode()->GetNodeType() )
581 : {
582 0 : bComplete = false;
583 0 : SwGrfNode* pNd = static_cast<SwGrfNode*>( GetNode());
584 :
585 0 : SwViewShell* pVSh = pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
586 0 : if( pVSh )
587 : {
588 0 : GraphicAttr aAttr;
589 0 : if( pNd->GetGrfObj().IsCached( pVSh->GetOut(), Point(),
590 0 : Prt().SSize(), &pNd->GetGraphicAttr( aAttr, this ) ))
591 : {
592 0 : for(SwViewShell rShell : pVSh->GetRingContainer())
593 : {
594 0 : SET_CURR_SHELL( &rShell );
595 0 : if( rShell.GetWin() )
596 : {
597 0 : if( rShell.IsPreview() )
598 0 : ::RepaintPagePreview( &rShell, Frm().SVRect() );
599 : else
600 0 : rShell.GetWin()->Invalidate( Frm().SVRect() );
601 : }
602 0 : }
603 0 : }
604 : }
605 : }
606 0 : break;
607 :
608 : case RES_UPDATE_ATTR:
609 0 : if (GetNode()->GetNodeType() != ND_GRFNODE) {
610 0 : break;
611 : }
612 : // fall through
613 : case RES_FMT_CHG:
614 0 : CLEARCACHE
615 0 : break;
616 :
617 : case RES_ATTRSET_CHG:
618 : {
619 : sal_uInt16 n;
620 171 : for( n = RES_GRFATR_BEGIN; n < RES_GRFATR_END; ++n )
621 342 : if( SfxItemState::SET == static_cast<const SwAttrSetChg*>(pOld)->GetChgSet()->
622 342 : GetItemState( n, false ))
623 : {
624 57 : CLEARCACHE
625 57 : break;
626 : }
627 57 : if( RES_GRFATR_END == n ) // not found
628 0 : return ;
629 : }
630 57 : break;
631 :
632 : case RES_GRAPHIC_PIECE_ARRIVED:
633 : case RES_GRAPHIC_ARRIVED:
634 : // i73788# - handle RES_LINKED_GRAPHIC_STREAM_ARRIVED as RES_GRAPHIC_ARRIVED
635 : case RES_LINKED_GRAPHIC_STREAM_ARRIVED:
636 15 : if ( GetNode()->GetNodeType() == ND_GRFNODE )
637 : {
638 15 : bComplete = false;
639 15 : SwGrfNode* pNd = static_cast<SwGrfNode*>( GetNode());
640 :
641 15 : CLEARCACHE
642 :
643 15 : SwRect aRect( Frm() );
644 :
645 15 : SwViewShell *pVSh = pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
646 15 : if( !pVSh )
647 0 : break;
648 :
649 30 : for(SwViewShell& rShell : pVSh->GetRingContainer())
650 : {
651 15 : SET_CURR_SHELL( &rShell );
652 15 : if( rShell.IsPreview() )
653 : {
654 0 : if( rShell.GetWin() )
655 0 : ::RepaintPagePreview( &rShell, aRect );
656 : }
657 27 : else if ( rShell.VisArea().IsOver( aRect ) &&
658 12 : OUTDEV_WINDOW == rShell.GetOut()->GetOutDevType() )
659 : {
660 : // invalidate instead of painting
661 12 : rShell.GetWin()->Invalidate( aRect.SVRect() );
662 : }
663 15 : }
664 : }
665 15 : break;
666 :
667 : default:
668 77 : if ( !pNew || !isGRFATR(nWhich) )
669 77 : return;
670 : }
671 :
672 72 : if( bComplete )
673 : {
674 57 : InvalidatePrt();
675 57 : SetCompletePaint();
676 : }
677 : }
678 :
679 18 : static void lcl_correctlyAlignRect( SwRect& rAlignedGrfArea, const SwRect& rInArea, vcl::RenderContext* pOut )
680 : {
681 :
682 18 : if(!pOut)
683 18 : return;
684 18 : Rectangle aPxRect = pOut->LogicToPixel( rInArea.SVRect() );
685 18 : Rectangle aNewPxRect( aPxRect );
686 36 : while( aNewPxRect.Left() < aPxRect.Left() )
687 : {
688 0 : rAlignedGrfArea.Left( rAlignedGrfArea.Left()+1 );
689 0 : aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() );
690 : }
691 36 : while( aNewPxRect.Top() < aPxRect.Top() )
692 : {
693 0 : rAlignedGrfArea.Top( rAlignedGrfArea.Top()+1 );
694 0 : aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() );
695 : }
696 36 : while( aNewPxRect.Bottom() > aPxRect.Bottom() )
697 : {
698 0 : rAlignedGrfArea.Bottom( rAlignedGrfArea.Bottom()-1 );
699 0 : aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() );
700 : }
701 36 : while( aNewPxRect.Right() > aPxRect.Right() )
702 : {
703 0 : rAlignedGrfArea.Right( rAlignedGrfArea.Right()-1 );
704 0 : aNewPxRect = pOut->LogicToPixel( rAlignedGrfArea.SVRect() );
705 : }
706 : }
707 :
708 104 : bool paintUsingPrimitivesHelper(
709 : vcl::RenderContext& rOutputDevice,
710 : const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
711 : const basegfx::B2DRange& rSourceRange,
712 : const basegfx::B2DRange& rTargetRange)
713 : {
714 104 : if(rSequence.hasElements() && !basegfx::fTools::equalZero(rSourceRange.getWidth()) && !basegfx::fTools::equalZero(rSourceRange.getHeight()))
715 : {
716 104 : if(!basegfx::fTools::equalZero(rTargetRange.getWidth()) && !basegfx::fTools::equalZero(rTargetRange.getHeight()))
717 : {
718 : // map graphic range to target range. This will e.g. automatically include
719 : // tme mapping from 1/100th mm content to twips if needed when the target
720 : // range is defined in twips
721 : const basegfx::B2DHomMatrix aMappingTransform(
722 : basegfx::tools::createSourceRangeTargetRangeTransform(
723 : rSourceRange,
724 104 : rTargetRange));
725 :
726 : // Fill ViewInformation. Use MappingTransform here, so there is no need to
727 : // embed the primitives to it. Use original TargetRange here so there is also
728 : // no need to embed the primitives to a MaskPrimitive for cropping. This works
729 : // only in this case where the graphic object cannot be rotated, though.
730 : const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
731 : aMappingTransform,
732 : rOutputDevice.GetViewTransformation(),
733 : rTargetRange,
734 : 0,
735 : 0.0,
736 104 : uno::Sequence< beans::PropertyValue >());
737 :
738 : // get a primitive processor for rendering
739 : drawinglayer::processor2d::BaseProcessor2D* pProcessor2D =
740 : drawinglayer::processor2d::createProcessor2DFromOutputDevice(
741 104 : rOutputDevice, aViewInformation2D);
742 :
743 104 : if(pProcessor2D)
744 : {
745 : // render and cleanup
746 104 : pProcessor2D->process(rSequence);
747 104 : delete pProcessor2D;
748 104 : return true;
749 0 : }
750 : }
751 : }
752 :
753 0 : return false;
754 : }
755 :
756 88 : void paintGraphicUsingPrimitivesHelper(vcl::RenderContext & rOutputDevice,
757 : GraphicObject const& rGrfObj, GraphicAttr const& rGraphicAttr,
758 : SwRect const& rAlignedGrfArea)
759 : {
760 : // unify using GraphicPrimitive2D
761 : // -> the primitive handles all crop and mirror stuff
762 : // -> the primitive renderer will create the needed pdf export data
763 : // -> if bitmap content, it will be cached system-dependent
764 : const basegfx::B2DRange aTargetRange(
765 176 : rAlignedGrfArea.Left(), rAlignedGrfArea.Top(),
766 264 : rAlignedGrfArea.Right(), rAlignedGrfArea.Bottom());
767 : const basegfx::B2DHomMatrix aTargetTransform(
768 : basegfx::tools::createScaleTranslateB2DHomMatrix(
769 : aTargetRange.getRange(),
770 88 : aTargetRange.getMinimum()));
771 :
772 176 : drawinglayer::primitive2d::Primitive2DSequence aContent(1);
773 88 : bool bDone(false);
774 :
775 : // #i125171# The mechanism to get lossless jpegs into pdf is based on having the original
776 : // file data (not the bitmap data) at the Graphic in the GfxLink (which has *nothing* to
777 : // do with the graphic being linked). This works well for DrawingLayer GraphicObjects (linked
778 : // and unlinked) but fails for linked Writer GraphicObjects. These have the URL in the
779 : // GraphicObject, but no GfxLink with the original file data when it's a linked graphic.
780 : // Since this blows up PDF size by a factor of 10 (the graphics get embedded as pixel maps
781 : // then) it is okay to add this workarund: In the needed case, load the graphic in a way to
782 : // get the GfxLink in the needed form and use that Graphic temporarily. Do this only when
783 : // - we have PDF export
784 : // - the GraphicObject is linked
785 : // - the Graphic has no GfxLink
786 : // - LosslessCompression is activated
787 : // - it's indeed a jpeg graphic (could be checked by the url ending, but is more reliable to check later)
788 : // In all other cases (normal repaint, print, etc...) use the available Graphic with the
789 : // already loaded pixel graphic as before this change.
790 88 : if (rOutputDevice.GetExtOutDevData() && rGrfObj.HasLink() && !rGrfObj.GetGraphic().IsLink())
791 : {
792 0 : const vcl::PDFExtOutDevData* pPDFExt = dynamic_cast< const vcl::PDFExtOutDevData* >(rOutputDevice.GetExtOutDevData());
793 :
794 0 : if (pPDFExt && pPDFExt->GetIsLosslessCompression())
795 : {
796 0 : Graphic aTempGraphic;
797 0 : INetURLObject aURL(rGrfObj.GetLink());
798 :
799 0 : if (GRFILTER_OK == GraphicFilter::GetGraphicFilter().ImportGraphic(aTempGraphic, aURL))
800 : {
801 0 : if(aTempGraphic.IsLink() && GFX_LINK_TYPE_NATIVE_JPG == aTempGraphic.GetLink().GetType())
802 : {
803 0 : aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
804 : aTargetTransform,
805 : aTempGraphic,
806 0 : rGraphicAttr);
807 0 : bDone = true;
808 : }
809 0 : }
810 : }
811 : }
812 :
813 88 : if(!bDone)
814 : {
815 176 : aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
816 : aTargetTransform,
817 : rGrfObj,
818 176 : rGraphicAttr);
819 : }
820 :
821 : paintUsingPrimitivesHelper(
822 : rOutputDevice,
823 : aContent,
824 : aTargetRange,
825 176 : aTargetRange);
826 88 : }
827 :
828 : /** Paint the graphic.
829 :
830 : We require either a QuickDraw-Bitmap or a graphic here. If we do not have
831 : either, we return a replacement.
832 :
833 : @todo use aligned rectangle for drawing graphic.
834 : @todo pixel-align coordinations for drawing graphic. */
835 146 : void SwNoTextFrm::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfArea ) const
836 : {
837 146 : SwViewShell* pShell = getRootFrm()->GetCurrShell();
838 :
839 146 : SwNoTextNode& rNoTNd = const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>(GetNode()));
840 146 : SwGrfNode* pGrfNd = rNoTNd.GetGrfNode();
841 146 : SwOLENode* pOLENd = rNoTNd.GetOLENode();
842 :
843 292 : const bool bPrn = pOut == rNoTNd.getIDocumentDeviceAccess()->getPrinter( false ) ||
844 292 : pOut->GetConnectMetaFile();
845 :
846 146 : const bool bIsChart = pOLENd && pOLENd->GetOLEObj().GetObject().IsChart();
847 :
848 : // calculate aligned rectangle from parameter <rGrfArea>.
849 : // Use aligned rectangle <aAlignedGrfArea> instead of <rGrfArea> in
850 : // the following code.
851 146 : SwRect aAlignedGrfArea = rGrfArea;
852 146 : ::SwAlignRect( aAlignedGrfArea, pShell );
853 :
854 146 : if( !bIsChart )
855 : {
856 : // Because for drawing a graphic left-top-corner and size coordinations are
857 : // used, these coordinations have to be determined on pixel level.
858 128 : ::SwAlignGrfRect( &aAlignedGrfArea, *pOut );
859 : }
860 : else //if( bIsChart )
861 : {
862 : // #i78025# charts own borders are not completely visible
863 : // the above pixel correction is not correct - at least not for charts
864 : // so a different pixel correction is chosen here
865 : // this might be a good idea for all other OLE objects also,
866 : // but as I cannot oversee the consequences I fix it only for charts for now
867 18 : lcl_correctlyAlignRect( aAlignedGrfArea, rGrfArea, pOut );
868 : }
869 :
870 146 : if( pGrfNd )
871 : {
872 : // Fix for bug fdo#33781
873 101 : const AntialiasingFlags nFormerAntialiasingAtOutput( pOut->GetAntialiasing() );
874 101 : if (pShell->Imp()->GetDrawView()->IsAntiAliasing())
875 : {
876 0 : pOut->SetAntialiasing( nFormerAntialiasingAtOutput | AntialiasingFlags::EnableB2dDraw );
877 : }
878 :
879 101 : bool bContinue = true;
880 101 : const GraphicObject& rGrfObj = pGrfNd->GetGrfObj(bPrn);
881 :
882 101 : GraphicAttr aGrfAttr;
883 101 : pGrfNd->GetGraphicAttr( aGrfAttr, this );
884 :
885 101 : if( !bPrn )
886 : {
887 : // #i73788#
888 95 : if ( pGrfNd->IsLinkedInputStreamReady() )
889 : {
890 0 : pGrfNd->UpdateLinkWithInputStream();
891 : }
892 : // #i85717#, #i90395# - check, if asynchronous retrieval
893 : // if input stream for the graphic is possible
894 285 : else if ( ( rGrfObj.GetType() == GRAPHIC_DEFAULT ||
895 108 : rGrfObj.GetType() == GRAPHIC_NONE ) &&
896 113 : pGrfNd->IsLinkedFile() &&
897 5 : pGrfNd->IsAsyncRetrieveInputStreamPossible() )
898 : {
899 5 : Size aTmpSz;
900 5 : ::sfx2::SvLinkSource* pGrfObj = pGrfNd->GetLink()->GetObj();
901 10 : if( !pGrfObj ||
902 5 : !pGrfObj->IsDataComplete() ||
903 0 : !(aTmpSz = pGrfNd->GetTwipSize()).Width() ||
904 5 : !aTmpSz.Height() || !pGrfNd->GetAutoFormatLvl() )
905 : {
906 5 : pGrfNd->TriggerAsyncRetrieveInputStream(); // #i73788#
907 : }
908 5 : OUString aText( pGrfNd->GetTitle() );
909 5 : if ( aText.isEmpty() )
910 5 : GetRealURL( *pGrfNd, aText );
911 5 : ::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, false );
912 5 : bContinue = false;
913 : }
914 : }
915 :
916 101 : if( bContinue )
917 : {
918 96 : if( rGrfObj.GetGraphic().IsSupportedGraphic())
919 : {
920 88 : const bool bAnimate = rGrfObj.IsAnimated() &&
921 0 : !pShell->IsPreview() &&
922 88 : !pShell->GetAccessibilityOptions()->IsStopAnimatedGraphics() &&
923 : // #i9684# Stop animation during printing/pdf export
924 88 : pShell->GetWin();
925 :
926 88 : if( bAnimate &&
927 0 : FindFlyFrm() != ::GetFlyFromMarked( 0, pShell ))
928 : {
929 : OutputDevice* pVout;
930 0 : if( pOut == pShell->GetOut() && SwRootFrm::FlushVout() )
931 0 : pVout = pOut, pOut = pShell->GetOut();
932 0 : else if( pShell->GetWin() &&
933 0 : OUTDEV_VIRDEV == pOut->GetOutDevType() )
934 0 : pVout = pOut, pOut = pShell->GetWin();
935 : else
936 0 : pVout = 0;
937 :
938 : OSL_ENSURE( OUTDEV_VIRDEV != pOut->GetOutDevType() ||
939 : pShell->GetViewOptions()->IsPDFExport(),
940 : "pOut should not be a virtual device" );
941 :
942 0 : pGrfNd->StartGraphicAnimation(pOut, aAlignedGrfArea.Pos(),
943 0 : aAlignedGrfArea.SSize(), sal_IntPtr(this),
944 0 : 0, GraphicManagerDrawFlags::STANDARD, pVout );
945 : }
946 : else
947 : {
948 : paintGraphicUsingPrimitivesHelper(*pOut,
949 88 : rGrfObj, aGrfAttr, aAlignedGrfArea);
950 : }
951 : }
952 : else
953 : {
954 8 : sal_uInt16 nResId = 0;
955 :
956 8 : if( GRAPHIC_NONE == rGrfObj.GetType() )
957 8 : nResId = STR_COMCORE_READERROR;
958 0 : else if ( !rGrfObj.GetGraphic().IsSupportedGraphic() )
959 0 : nResId = STR_COMCORE_CANT_SHOW;
960 :
961 8 : OUString aText;
962 24 : if ( !nResId &&
963 16 : (aText = pGrfNd->GetTitle()).isEmpty() &&
964 0 : (!GetRealURL( *pGrfNd, aText ) || aText.isEmpty()))
965 : {
966 0 : nResId = STR_COMCORE_READERROR;
967 : }
968 8 : if ( nResId )
969 8 : aText = SW_RESSTR( nResId );
970 :
971 8 : ::lcl_PaintReplacement( aAlignedGrfArea, aText, *pShell, this, true );
972 : }
973 : }
974 :
975 101 : if ( pShell->Imp()->GetDrawView()->IsAntiAliasing() )
976 0 : pOut->SetAntialiasing( nFormerAntialiasingAtOutput );
977 : }
978 : else // bIsChart || pOLENd
979 : {
980 : // Fix for bug fdo#33781
981 45 : const AntialiasingFlags nFormerAntialiasingAtOutput( pOut->GetAntialiasing() );
982 45 : if (pShell->Imp()->GetDrawView()->IsAntiAliasing())
983 : {
984 0 : AntialiasingFlags nNewAntialiasingAtOutput = nFormerAntialiasingAtOutput | AntialiasingFlags::EnableB2dDraw;
985 :
986 : // #i99665#
987 : // Adjust AntiAliasing mode at output device for chart OLE
988 0 : if ( pOLENd->IsChart() )
989 0 : nNewAntialiasingAtOutput |= AntialiasingFlags::PixelSnapHairline;
990 :
991 0 : pOut->SetAntialiasing( nNewAntialiasingAtOutput );
992 : }
993 :
994 45 : bool bDone(false);
995 :
996 45 : if(bIsChart)
997 : {
998 18 : const uno::Reference< frame::XModel > aXModel(pOLENd->GetOLEObj().GetOleRef()->getComponent(), uno::UNO_QUERY);
999 :
1000 18 : if(aXModel.is())
1001 : {
1002 16 : basegfx::B2DRange aSourceRange;
1003 :
1004 : const drawinglayer::primitive2d::Primitive2DSequence aSequence(
1005 : ChartHelper::tryToGetChartContentAsPrimitive2DSequence(
1006 : aXModel,
1007 16 : aSourceRange));
1008 :
1009 16 : if(aSequence.hasElements() && !aSourceRange.isEmpty())
1010 : {
1011 : const basegfx::B2DRange aTargetRange(
1012 32 : aAlignedGrfArea.Left(), aAlignedGrfArea.Top(),
1013 48 : aAlignedGrfArea.Right(), aAlignedGrfArea.Bottom());
1014 :
1015 : bDone = paintUsingPrimitivesHelper(
1016 : *pOut,
1017 : aSequence,
1018 : aSourceRange,
1019 16 : aTargetRange);
1020 16 : }
1021 18 : }
1022 : }
1023 :
1024 45 : if(!bDone && pOLENd)
1025 : {
1026 29 : Point aPosition(aAlignedGrfArea.Pos());
1027 29 : Size aSize(aAlignedGrfArea.SSize());
1028 :
1029 29 : const Graphic* pGraphic = pOLENd->GetGraphic();
1030 29 : if ( pGraphic && pGraphic->GetType() != GRAPHIC_NONE )
1031 : {
1032 29 : pGraphic->Draw( pOut, aPosition, aSize );
1033 :
1034 : // shade the representation if the object is activated outplace
1035 29 : uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef();
1036 29 : if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::ACTIVE )
1037 : {
1038 0 : ::svt::EmbeddedObjectRef::DrawShading( Rectangle( aPosition, aSize ), pOut );
1039 29 : }
1040 : }
1041 : else
1042 0 : ::svt::EmbeddedObjectRef::DrawPaintReplacement( Rectangle( aPosition, aSize ), pOLENd->GetOLEObj().GetCurrentPersistName(), pOut );
1043 :
1044 29 : sal_Int64 nMiscStatus = pOLENd->GetOLEObj().GetOleRef()->getStatus( pOLENd->GetAspect() );
1045 50 : if ( !bPrn && pShell->ISA( SwCrsrShell ) && (
1046 42 : (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE) ||
1047 21 : pOLENd->GetOLEObj().GetObject().IsGLChart()))
1048 : {
1049 0 : const SwFlyFrm *pFly = FindFlyFrm();
1050 : assert( pFly != NULL );
1051 0 : static_cast<SwFEShell*>(pShell)->ConnectObj( pOLENd->GetOLEObj().GetObject(), pFly->Prt(), pFly->Frm());
1052 : }
1053 : }
1054 :
1055 : // see #i99665#
1056 45 : if (pShell->Imp()->GetDrawView()->IsAntiAliasing())
1057 : {
1058 0 : pOut->SetAntialiasing( nFormerAntialiasingAtOutput );
1059 : }
1060 : }
1061 146 : }
1062 :
1063 173 : bool SwNoTextFrm::IsTransparent() const
1064 : {
1065 173 : const SwViewShell* pSh = getRootFrm()->GetCurrShell();
1066 173 : if ( !pSh || !pSh->GetViewOptions()->IsGraphic() )
1067 0 : return true;
1068 :
1069 : const SwGrfNode *pNd;
1070 173 : if( 0 != (pNd = GetNode()->GetGrfNode()) )
1071 120 : return pNd->IsTransparent();
1072 :
1073 : //#29381# OLE are always transparent
1074 53 : return true;
1075 : }
1076 :
1077 1044 : void SwNoTextFrm::StopAnimation( OutputDevice* pOut ) const
1078 : {
1079 : // Stop animated graphics
1080 1044 : const SwGrfNode* pGrfNd = dynamic_cast< const SwGrfNode* >(GetNode()->GetGrfNode());
1081 :
1082 1044 : if( pGrfNd && pGrfNd->IsAnimated() )
1083 : {
1084 0 : const_cast< SwGrfNode* >(pGrfNd)->StopGraphicAnimation( pOut, sal_IntPtr(this) );
1085 : }
1086 1044 : }
1087 :
1088 1096 : bool SwNoTextFrm::HasAnimation() const
1089 : {
1090 1096 : const SwGrfNode* pGrfNd = GetNode()->GetGrfNode();
1091 1096 : return pGrfNd && pGrfNd->IsAnimated();
1092 177 : }
1093 :
1094 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|