LibreOffice Module sw (master) 1
paintfrm.cxx
Go to the documentation of this file.
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 <utility>
21#include <vcl/canvastools.hxx>
22#include <vcl/lazydelete.hxx>
23#include <sfx2/docfile.hxx>
24#include <sfx2/printer.hxx>
25#include <sfx2/progress.hxx>
26#include <editeng/brushitem.hxx>
27#include <editeng/prntitem.hxx>
28#include <editeng/boxitem.hxx>
29#include <editeng/shaditem.hxx>
30#include <svx/ctredlin.hxx>
31#include <svx/framelink.hxx>
32#include <drawdoc.hxx>
33#include <tgrditem.hxx>
34#include <calbck.hxx>
35#include <fmtsrnd.hxx>
36#include <fmtclds.hxx>
37#include <fmturl.hxx>
38#include <strings.hrc>
39#include <swmodule.hxx>
40#include <rootfrm.hxx>
41#include <pagefrm.hxx>
42#include <section.hxx>
43#include <sectfrm.hxx>
44#include <viewimp.hxx>
45#include <dflyobj.hxx>
46#include <flyfrm.hxx>
47#include <frmatr.hxx>
48#include <frmtool.hxx>
49#include <viewopt.hxx>
50#include <dview.hxx>
51#include <dcontact.hxx>
52#include <txtfrm.hxx>
53#include <ftnfrm.hxx>
54#include <tabfrm.hxx>
55#include <rowfrm.hxx>
56#include <cellfrm.hxx>
57#include <notxtfrm.hxx>
58#include <layact.hxx>
59#include <pagedesc.hxx>
60#include <ptqueue.hxx>
61#include <noteurl.hxx>
62#include "virtoutp.hxx"
63#include <lineinfo.hxx>
64#include <dbg_lay.hxx>
65#include <docsh.hxx>
66#include <svx/svdogrp.hxx>
67#include <sortedobjs.hxx>
69#include <bodyfrm.hxx>
70#include <hffrm.hxx>
71#include <colfrm.hxx>
73#include <swfont.hxx>
74
82
83#include <ndole.hxx>
84#include <PostItMgr.hxx>
86#include <vcl/settings.hxx>
87
89
91
92#include <bitmaps.hlst>
101#include <svx/unoapi.hxx>
102#include <svx/svdpagv.hxx>
103#include <svx/xfillit0.hxx>
107#include <sal/log.hxx>
108
109#include <memory>
110#include <vector>
111#include <algorithm>
112#include <wrtsh.hxx>
113#include <edtwin.hxx>
114#include <view.hxx>
115#include <paintfrm.hxx>
116#include <textboxhelper.hxx>
118
119#include <vcl/BitmapTools.hxx>
120#include <comphelper/lok.hxx>
122#include <vcl/GraphicLoader.hxx>
124
125#include <svl/style.hxx>
126#include <ndtxt.hxx>
127#include <unotools/configmgr.hxx>
128#include <vcl/hatch.hxx>
129
130using namespace ::editeng;
131using namespace ::com::sun::star;
132
133namespace {
134
135struct SwPaintProperties;
136
137//Class declaration; here because they are only used in this file
138enum class SubColFlags {
139 Page = 0x01, //Helplines of the page
140 Tab = 0x08, //Helplines inside tables
141 Fly = 0x10, //Helplines inside fly frames
142 Sect = 0x20, //Helplines inside sections
143};
144
145}
146
147namespace o3tl {
148 template<> struct typed_flags<SubColFlags> : is_typed_flags<SubColFlags, 0x39> {};
149}
150
151namespace {
152
153// Classes collecting the border lines and help lines
154class SwLineRect : public SwRect
155{
157 SvxBorderLineStyle m_nStyle;
158 const SwTabFrame* m_pTabFrame;
159 SubColFlags m_nSubColor; //colorize subsidiary lines
160 bool m_bPainted; //already painted?
161 sal_uInt8 m_nLock; //To distinguish the line and the hell layer.
162public:
163 SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderLineStyle nStyle,
164 const SwTabFrame *pT , const SubColFlags nSCol );
165
166 const Color& GetColor() const { return m_aColor; }
167 SvxBorderLineStyle GetStyle() const { return m_nStyle; }
168 const SwTabFrame* GetTab() const { return m_pTabFrame; }
169 void SetPainted() { m_bPainted = true; }
170 void Lock(bool bLock)
171 {
172 if (bLock)
173 ++m_nLock;
174 else if (m_nLock)
175 --m_nLock;
176 }
177 bool IsPainted() const { return m_bPainted; }
178 bool IsLocked() const { return m_nLock != 0; }
179 SubColFlags GetSubColor() const { return m_nSubColor; }
180
181 bool MakeUnion(const SwRect& rRect, SwPaintProperties const& properties);
182};
183
184}
185
186#ifdef IOS
187static void dummy_function()
188{
189 pid_t pid = getpid();
190 (void) pid;
191}
192#endif
193
194namespace {
195
196class SwLineRects
197{
198public:
199 std::vector<SwLineRect> m_aLineRects;
200 typedef std::vector< SwLineRect >::const_iterator const_iterator;
201 typedef std::vector< SwLineRect >::iterator iterator;
202 typedef std::vector< SwLineRect >::reverse_iterator reverse_iterator;
203 typedef std::vector< SwLineRect >::size_type size_type;
204 size_t m_nLastCount; //avoid unnecessary cycles in PaintLines
205 SwLineRects()
206 : m_nLastCount(0)
207 {
208#ifdef IOS
209 // Work around what is either a compiler bug in Xcode 5.1.1,
210 // or some unknown problem in this file. If I ifdef out this
211 // call, I get a crash in SwSubsRects::PaintSubsidiary: the
212 // address of the rLi reference variable is claimed to be
213 // 0x4000000!
214 dummy_function();
215#endif
216 }
217 void AddLineRect( const SwRect& rRect, const Color *pColor, const SvxBorderLineStyle nStyle,
218 const SwTabFrame *pTab, const SubColFlags nSCol, SwPaintProperties const &properties );
219 void ConnectEdges( OutputDevice const *pOut, SwPaintProperties const &properties );
220 void PaintLines ( OutputDevice *pOut, SwPaintProperties const &properties );
221 void LockLines( bool bLock );
222
223 //Limit lines to 100
224 bool isFull() const { return m_aLineRects.size() > 100; }
225};
226
227class SwSubsRects : public SwLineRects
228{
229 void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects, SwPaintProperties const &properties );
230public:
231 void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects, SwPaintProperties const &properties );
232};
233
234class BorderLines
235{
237public:
238 void AddBorderLines(drawinglayer::primitive2d::Primitive2DContainer&& rContainer);
240 {
242 lines.swap(m_Lines);
243 return lines;
244 }
245};
246
247}
248
249// Default zoom factor
250const double aEdgeScale = 0.5;
251
252//To optimize the expensive RetouchColor determination
254
255namespace sw
256{
258{
259 return &aGlobalRetoucheColor;
260}
261}
262
263namespace {
264
268struct SwPaintProperties {
269 // Only repaint the Fly content as well as the background of the Fly content if
270 // a metafile is taken of the Fly.
271 bool bSFlyMetafile;
272 VclPtr<OutputDevice> pSFlyMetafileOut;
273 SwViewShell *pSGlobalShell;
274
275 // Retouch for transparent Flys is done by the background of the Flys.
276 // The Fly itself should certainly not be spared out. See PaintSwFrameBackground and
277 // lcl_SubtractFlys()
278 SwFlyFrame *pSRetoucheFly;
279 SwFlyFrame *pSRetoucheFly2;
280 SwFlyFrame *pSFlyOnlyDraw;
281
282 // The borders will be collected in pSLines during the Paint and later
283 // possibly merge them.
284 // The help lines will be collected and merged in gProp.pSSubsLines. These will
285 // be compared with pSLines before the work in order to avoid help lines
286 // to hide borders.
287 std::unique_ptr<BorderLines> pBLines;
288 std::unique_ptr<SwLineRects> pSLines;
289 std::unique_ptr<SwSubsRects> pSSubsLines;
290
291 // global variable for sub-lines of body, header, footer, section and footnote frames.
292 std::unique_ptr<SwSubsRects> pSSpecSubsLines;
293 SfxProgress *pSProgress;
294
295 // Sizes of a pixel and the corresponding halves. Will be reset when
296 // entering SwRootFrame::PaintSwFrame
297 tools::Long nSPixelSzW;
298 tools::Long nSPixelSzH;
299 tools::Long nSHalfPixelSzW;
300 tools::Long nSHalfPixelSzH;
301 tools::Long nSMinDistPixelW;
302 tools::Long nSMinDistPixelH;
303
304 Color aSGlobalRetoucheColor;
305
306 // Current zoom factor
307 double aSScaleX;
308 double aSScaleY;
309
310 SwPaintProperties()
311 : bSFlyMetafile(false)
312 , pSFlyMetafileOut(nullptr)
313 , pSGlobalShell(nullptr)
314 , pSRetoucheFly(nullptr)
315 , pSRetoucheFly2(nullptr)
316 , pSFlyOnlyDraw(nullptr)
317 , pSProgress(nullptr)
318 , nSPixelSzW(0)
319 , nSPixelSzH(0)
320 , nSHalfPixelSzW(0)
321 , nSHalfPixelSzH(0)
322 , nSMinDistPixelW(0)
323 , nSMinDistPixelH(0)
324 , aSScaleX(1)
325 , aSScaleY(1)
326 {
327 }
328
329};
330
331}
332
333static SwPaintProperties gProp;
334
336{
337 return !gProp.pSGlobalShell->GetViewOptions()->IsPagePreview() &&
338 !gProp.pSGlobalShell->GetViewOptions()->IsReadonly() &&
339 !gProp.pSGlobalShell->GetViewOptions()->IsFormView() &&
340 gProp.pSGlobalShell->GetViewOptions()->IsObjectBoundaries();
341}
342//other subsidiary lines enabled?
344{
345 return !gProp.pSGlobalShell->GetViewOptions()->IsPagePreview() &&
346 !gProp.pSGlobalShell->GetViewOptions()->IsReadonly() &&
347 !gProp.pSGlobalShell->GetViewOptions()->IsFormView() &&
348 !gProp.pSGlobalShell->GetViewOptions()->IsWhitespaceHidden() &&
349 gProp.pSGlobalShell->GetViewOptions()->IsDocBoundaries();
350}
351//subsidiary lines for sections
353{
354 return !gProp.pSGlobalShell->GetViewOptions()->IsPagePreview() &&
355 !gProp.pSGlobalShell->GetViewOptions()->IsReadonly() &&
356 !gProp.pSGlobalShell->GetViewOptions()->IsFormView() &&
357 gProp.pSGlobalShell->GetViewOptions()->IsSectionBoundaries();
358}
359
360
361namespace {
362
363bool isTableBoundariesEnabled()
364{
365 if (!gProp.pSGlobalShell->GetViewOptions()->IsTable())
366 return false;
367
368 if (gProp.pSGlobalShell->GetViewOptions()->IsPagePreview())
369 return false;
370
371 if (gProp.pSGlobalShell->GetViewOptions()->IsReadonly())
372 return false;
373
374 if (gProp.pSGlobalShell->GetViewOptions()->IsFormView())
375 return false;
376
377 return gProp.pSGlobalShell->GetViewOptions()->IsTableBoundaries();
378}
379
380}
381
389{
390 // determine 'small' twip-to-pixel relation
391 bool bSmallTwipToPxRelW = false;
392 bool bSmallTwipToPxRelH = false;
393 {
394 Size aCheckTwipToPxRelSz( pOut->PixelToLogic( Size( 100, 100 )) );
395 if ( (aCheckTwipToPxRelSz.Width()/100.0) < 2.0 )
396 {
397 bSmallTwipToPxRelW = true;
398 }
399 if ( (aCheckTwipToPxRelSz.Height()/100.0) < 2.0 )
400 {
401 bSmallTwipToPxRelH = true;
402 }
403 }
404
405 Size aSz( pOut->PixelToLogic( Size( 1,1 )) );
406
407 gProp.nSPixelSzW = aSz.Width();
408 if( !gProp.nSPixelSzW )
409 gProp.nSPixelSzW = 1;
410 gProp.nSPixelSzH = aSz.Height();
411 if( !gProp.nSPixelSzH )
412 gProp.nSPixelSzH = 1;
413
414 // consider 'small' twip-to-pixel relations
415 if ( !bSmallTwipToPxRelW )
416 {
417 gProp.nSHalfPixelSzW = gProp.nSPixelSzW / 2 + 1;
418 }
419 else
420 {
421 gProp.nSHalfPixelSzW = 0;
422 }
423 // consider 'small' twip-to-pixel relations
424 if ( !bSmallTwipToPxRelH )
425 {
426 gProp.nSHalfPixelSzH = gProp.nSPixelSzH / 2 + 1;
427 }
428 else
429 {
430 gProp.nSHalfPixelSzH = 0;
431 }
432
433 gProp.nSMinDistPixelW = gProp.nSPixelSzW * 2 + 1;
434 gProp.nSMinDistPixelH = gProp.nSPixelSzH * 2 + 1;
435
436 const MapMode &rMap = pOut->GetMapMode();
437 gProp.aSScaleX = double(rMap.GetScaleX());
438 gProp.aSScaleY = double(rMap.GetScaleY());
439}
440
441namespace {
442
446class SwSavePaintStatics : public SwPaintProperties
447{
448public:
449 SwSavePaintStatics();
450 ~SwSavePaintStatics();
451};
452
453}
454
455SwSavePaintStatics::SwSavePaintStatics()
456{
457 // Saving globales
458 bSFlyMetafile = gProp.bSFlyMetafile;
459 pSGlobalShell = gProp.pSGlobalShell;
460 pSFlyMetafileOut = gProp.pSFlyMetafileOut;
461 pSRetoucheFly = gProp.pSRetoucheFly;
462 pSRetoucheFly2 = gProp.pSRetoucheFly2;
463 pSFlyOnlyDraw = gProp.pSFlyOnlyDraw;
464 pBLines = std::move(gProp.pBLines);
465 pSLines = std::move(gProp.pSLines);
466 pSSubsLines = std::move(gProp.pSSubsLines);
467 pSSpecSubsLines = std::move(gProp.pSSpecSubsLines);
468 pSProgress = gProp.pSProgress;
469 nSPixelSzW = gProp.nSPixelSzW;
470 nSPixelSzH = gProp.nSPixelSzH;
471 nSHalfPixelSzW = gProp.nSHalfPixelSzW;
472 nSHalfPixelSzH = gProp.nSHalfPixelSzH;
473 nSMinDistPixelW = gProp.nSMinDistPixelW;
474 nSMinDistPixelH = gProp.nSMinDistPixelH ;
475 aSGlobalRetoucheColor = aGlobalRetoucheColor;
476 aSScaleX = gProp.aSScaleX;
477 aSScaleY = gProp.aSScaleY;
478
479 // Restoring globales to default
480 gProp.bSFlyMetafile = false;
481 gProp.pSFlyMetafileOut = nullptr;
482 gProp.pSRetoucheFly = nullptr;
483 gProp.pSRetoucheFly2 = nullptr;
484 gProp.nSPixelSzW = gProp.nSPixelSzH =
485 gProp.nSHalfPixelSzW = gProp.nSHalfPixelSzH =
486 gProp.nSMinDistPixelW = gProp.nSMinDistPixelH = 0;
487 gProp.aSScaleX = gProp.aSScaleY = 1.0;
488 gProp.pSProgress = nullptr;
489}
490
491SwSavePaintStatics::~SwSavePaintStatics()
492{
493 // Restoring globales to saved one
494 gProp.pSGlobalShell = pSGlobalShell;
495 gProp.bSFlyMetafile = bSFlyMetafile;
496 gProp.pSFlyMetafileOut = pSFlyMetafileOut;
497 gProp.pSRetoucheFly = pSRetoucheFly;
498 gProp.pSRetoucheFly2 = pSRetoucheFly2;
499 gProp.pSFlyOnlyDraw = pSFlyOnlyDraw;
500 gProp.pBLines = std::move(pBLines);
501 gProp.pSLines = std::move(pSLines);
502 gProp.pSSubsLines = std::move(pSSubsLines);
503 gProp.pSSpecSubsLines = std::move(pSSpecSubsLines);
504 gProp.pSProgress = pSProgress;
505 gProp.nSPixelSzW = nSPixelSzW;
506 gProp.nSPixelSzH = nSPixelSzH;
507 gProp.nSHalfPixelSzW = nSHalfPixelSzW;
508 gProp.nSHalfPixelSzH = nSHalfPixelSzH;
509 gProp.nSMinDistPixelW = nSMinDistPixelW;
510 gProp.nSMinDistPixelH = nSMinDistPixelH;
511 aGlobalRetoucheColor = aSGlobalRetoucheColor;
512 gProp.aSScaleX = aSScaleX;
513 gProp.aSScaleY = aSScaleY;
514}
515
516void BorderLines::AddBorderLines(drawinglayer::primitive2d::Primitive2DContainer&& rContainer)
517{
518 if(!rContainer.empty())
519 {
520 m_Lines.append(std::move(rContainer));
521 }
522}
523
524SwLineRect::SwLineRect(const SwRect& rRect, const Color* pCol, const SvxBorderLineStyle nStyl,
525 const SwTabFrame* pT, const SubColFlags nSCol)
526 : SwRect(rRect)
527 , m_nStyle(nStyl)
528 , m_pTabFrame(pT)
529 , m_nSubColor(nSCol)
530 , m_bPainted(false)
531 , m_nLock(0)
532{
533 if ( pCol != nullptr )
534 m_aColor = *pCol;
535}
536
537bool SwLineRect::MakeUnion( const SwRect &rRect, SwPaintProperties const & properties)
538{
539 // It has already been tested outside, whether the rectangles have
540 // the same orientation (horizontal or vertical), color, etc.
541 if ( Height() > Width() ) //Vertical line
542 {
543 if ( Left() == rRect.Left() && Width() == rRect.Width() )
544 {
545 // Merge when there is no gap between the lines
546 const tools::Long nAdd = properties.nSPixelSzW + properties.nSHalfPixelSzW;
547 if ( Bottom() + nAdd >= rRect.Top() &&
548 Top() - nAdd <= rRect.Bottom() )
549 {
550 Bottom( std::max( Bottom(), rRect.Bottom() ) );
551 Top ( std::min( Top(), rRect.Top() ) );
552 return true;
553 }
554 }
555 }
556 else
557 {
558 if ( Top() == rRect.Top() && Height() == rRect.Height() )
559 {
560 // Merge when there is no gap between the lines
561 const tools::Long nAdd = properties.nSPixelSzW + properties.nSHalfPixelSzW;
562 if ( Right() + nAdd >= rRect.Left() &&
563 Left() - nAdd <= rRect.Right() )
564 {
565 Right( std::max( Right(), rRect.Right() ) );
566 Left ( std::min( Left(), rRect.Left() ) );
567 return true;
568 }
569 }
570 }
571 return false;
572}
573
574void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderLineStyle nStyle,
575 const SwTabFrame *pTab, const SubColFlags nSCol, SwPaintProperties const & properties )
576{
577 // Loop backwards because lines which can be combined, can usually be painted
578 // in the same context
579 for (reverse_iterator it = m_aLineRects.rbegin(); it != m_aLineRects.rend(); ++it)
580 {
581 SwLineRect &rLRect = *it;
582 // Test for the orientation, color, table
583 if ( rLRect.GetTab() == pTab &&
584 !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol &&
585 (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) &&
586 (pCol && rLRect.GetColor() == *pCol) )
587 {
588 if ( rLRect.MakeUnion( rRect, properties ) )
589 return;
590 }
591 }
592 m_aLineRects.emplace_back(rRect, pCol, nStyle, pTab, nSCol);
593}
594
595void SwLineRects::ConnectEdges( OutputDevice const *pOut, SwPaintProperties const & properties )
596{
597 if ( pOut->GetOutDevType() != OUTDEV_PRINTER )
598 {
599 // I'm not doing anything for a too small zoom
600 if ( properties.aSScaleX < aEdgeScale || properties.aSScaleY < aEdgeScale )
601 return;
602 }
603
604 static const tools::Long nAdd = 20;
605
606 std::vector<SwLineRect*> aCheck;
607
608 for (size_t i = 0; i < m_aLineRects.size(); ++i)
609 {
610 SwLineRect& rL1 = m_aLineRects[i];
611 if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() )
612 continue;
613
614 aCheck.clear();
615
616 const bool bVert = rL1.Height() > rL1.Width();
617 tools::Long nL1a, nL1b, nL1c, nL1d;
618
619 if ( bVert )
620 {
621 nL1a = rL1.Top(); nL1b = rL1.Left();
622 nL1c = rL1.Right(); nL1d = rL1.Bottom();
623 }
624 else
625 {
626 nL1a = rL1.Left(); nL1b = rL1.Top();
627 nL1c = rL1.Bottom(); nL1d = rL1.Right();
628 }
629
630 // Collect all lines to possibly link with i1
631 for (iterator it2 = m_aLineRects.begin(); it2 != m_aLineRects.end(); ++it2)
632 {
633 SwLineRect &rL2 = *it2;
634 if ( rL2.GetTab() != rL1.GetTab() ||
635 rL2.IsPainted() ||
636 rL2.IsLocked() ||
637 (bVert == (rL2.Height() > rL2.Width())) )
638 continue;
639
640 tools::Long nL2a, nL2b, nL2c, nL2d;
641 if ( bVert )
642 {
643 nL2a = rL2.Top(); nL2b = rL2.Left();
644 nL2c = rL2.Right(); nL2d = rL2.Bottom();
645 }
646 else
647 {
648 nL2a = rL2.Left(); nL2b = rL2.Top();
649 nL2c = rL2.Bottom(); nL2d = rL2.Right();
650 }
651
652 if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) &&
653 ((nL1b > nL2b && nL1c < nL2c) ||
654 (nL1c >= nL2c && nL1b - nAdd < nL2c) ||
655 (nL1b <= nL2b && nL1c + nAdd > nL2b)) )
656 {
657 aCheck.push_back( &rL2 );
658 }
659 }
660 if ( aCheck.size() < 2 )
661 continue;
662
663 bool bRemove = false;
664
665 // For each line test all following ones.
666 for ( size_t k = 0; !bRemove && k < aCheck.size(); ++k )
667 {
668 SwLineRect &rR1 = *aCheck[k];
669
670 for ( size_t k2 = k+1; !bRemove && k2 < aCheck.size(); ++k2 )
671 {
672 SwLineRect &rR2 = *aCheck[k2];
673 if ( bVert )
674 {
675 SwLineRect *pLA = nullptr;
676 SwLineRect *pLB = nullptr;
677 if ( rR1.Top() < rR2.Top() )
678 {
679 pLA = &rR1; pLB = &rR2;
680 }
681 else if ( rR1.Top() > rR2.Top() )
682 {
683 pLA = &rR2; pLB = &rR1;
684 }
685 // are k1 and k2 describing a double line?
686 if ( pLA && pLA->Bottom() + 60 > pLB->Top() )
687 {
688 if ( rL1.Top() < pLA->Top() )
689 {
690 if ( rL1.Bottom() == pLA->Bottom() )
691 continue; //Small mistake (where?)
692
693 SwRect aIns( rL1 );
694 aIns.Bottom( pLA->Bottom() );
695 if ( !rL1.Contains( aIns ) )
696 continue;
697 m_aLineRects.emplace_back(aIns, &rL1.GetColor(),
698 SvxBorderLineStyle::SOLID, rL1.GetTab(),
699 SubColFlags::Tab);
700 if ( isFull() )
701 {
702 --i;
703 k = aCheck.size();
704 break;
705 }
706 }
707
708 if ( rL1.Bottom() > pLB->Bottom() )
709 rL1.Top( pLB->Top() ); // extend i1 on the top
710 else
711 bRemove = true; //stopping, remove i1
712 }
713 }
714 else
715 {
716 SwLineRect *pLA = nullptr;
717 SwLineRect *pLB = nullptr;
718 if ( rR1.Left() < rR2.Left() )
719 {
720 pLA = &rR1; pLB = &rR2;
721 }
722 else if ( rR1.Left() > rR2.Left() )
723 {
724 pLA = &rR2; pLB = &rR1;
725 }
726 // Is it double line?
727 if ( pLA && pLA->Right() + 60 > pLB->Left() )
728 {
729 if ( rL1.Left() < pLA->Left() )
730 {
731 if ( rL1.Right() == pLA->Right() )
732 continue; //small error
733
734 SwRect aIns( rL1 );
735 aIns.Right( pLA->Right() );
736 if ( !rL1.Contains( aIns ) )
737 continue;
738 m_aLineRects.emplace_back(aIns, &rL1.GetColor(),
739 SvxBorderLineStyle::SOLID, rL1.GetTab(),
740 SubColFlags::Tab);
741 if ( isFull() )
742 {
743 --i;
744 k = aCheck.size();
745 break;
746 }
747 }
748 if ( rL1.Right() > pLB->Right() )
749 rL1.Left( pLB->Left() );
750 else
751 bRemove = true;
752 }
753 }
754 }
755 }
756 if ( bRemove )
757 {
758 m_aLineRects.erase(m_aLineRects.begin() + i);
759 --i;
760 }
761 }
762}
763
764void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects, SwPaintProperties const & properties )
765{
766 // All help lines that are covered by any border will be removed or split
767 for (size_t i = 0; i < m_aLineRects.size(); ++i)
768 {
769 // get a copy instead of a reference, because an <insert> may destroy
770 // the object due to a necessary array resize.
771 const SwLineRect aSubsLineRect(m_aLineRects[i]);
772
773 // add condition <aSubsLineRect.IsLocked()> in order to consider only
774 // border lines, which are *not* locked.
775 if ( aSubsLineRect.IsPainted() ||
776 aSubsLineRect.IsLocked() )
777 continue;
778
779 const bool bVerticalSubs = aSubsLineRect.Height() > aSubsLineRect.Width();
780 SwRect aSubsRect( aSubsLineRect );
781 if ( bVerticalSubs )
782 {
783 aSubsRect.AddLeft ( - (properties.nSPixelSzW+properties.nSHalfPixelSzW) );
784 aSubsRect.AddRight ( properties.nSPixelSzW+properties.nSHalfPixelSzW );
785 }
786 else
787 {
788 aSubsRect.AddTop ( - (properties.nSPixelSzH+properties.nSHalfPixelSzH) );
789 aSubsRect.AddBottom( properties.nSPixelSzH+properties.nSHalfPixelSzH );
790 }
791 for (const_iterator itK = rRects.m_aLineRects.begin(); itK != rRects.m_aLineRects.end();
792 ++itK)
793 {
794 const SwLineRect &rLine = *itK;
795
796 // do *not* consider painted or locked border lines.
797 // #i1837# - locked border lines have to be considered.
798 if ( rLine.IsLocked () )
799 continue;
800
801 if ( !bVerticalSubs == ( rLine.Height() > rLine.Width() ) ) //same direction?
802 continue;
803
804 if ( aSubsRect.Overlaps( rLine ) )
805 {
806 if ( bVerticalSubs ) // Vertical?
807 {
808 if ( aSubsRect.Left() <= rLine.Right() &&
809 aSubsRect.Right() >= rLine.Left() )
810 {
811 tools::Long nTmp = rLine.Top()-(properties.nSPixelSzH+1);
812 if ( aSubsLineRect.Top() < nTmp )
813 {
814 SwRect aNewSubsRect( aSubsLineRect );
815 aNewSubsRect.Bottom( nTmp );
816 m_aLineRects.emplace_back(aNewSubsRect, nullptr,
817 aSubsLineRect.GetStyle(), nullptr,
818 aSubsLineRect.GetSubColor());
819 }
820 nTmp = rLine.Bottom()+properties.nSPixelSzH+1;
821 if ( aSubsLineRect.Bottom() > nTmp )
822 {
823 SwRect aNewSubsRect( aSubsLineRect );
824 aNewSubsRect.Top( nTmp );
825 m_aLineRects.emplace_back(aNewSubsRect, nullptr,
826 aSubsLineRect.GetStyle(), nullptr,
827 aSubsLineRect.GetSubColor());
828 }
829 m_aLineRects.erase(m_aLineRects.begin() + i);
830 --i;
831 break;
832 }
833 }
834 else // Horizontal
835 {
836 if ( aSubsRect.Top() <= rLine.Bottom() &&
837 aSubsRect.Bottom() >= rLine.Top() )
838 {
839 tools::Long nTmp = rLine.Left()-(properties.nSPixelSzW+1);
840 if ( aSubsLineRect.Left() < nTmp )
841 {
842 SwRect aNewSubsRect( aSubsLineRect );
843 aNewSubsRect.Right( nTmp );
844 m_aLineRects.emplace_back(aNewSubsRect, nullptr,
845 aSubsLineRect.GetStyle(), nullptr,
846 aSubsLineRect.GetSubColor());
847 }
848 nTmp = rLine.Right()+properties.nSPixelSzW+1;
849 if ( aSubsLineRect.Right() > nTmp )
850 {
851 SwRect aNewSubsRect( aSubsLineRect );
852 aNewSubsRect.Left( nTmp );
853 m_aLineRects.emplace_back(aNewSubsRect, nullptr,
854 aSubsLineRect.GetStyle(), nullptr,
855 aSubsLineRect.GetSubColor());
856 }
857 m_aLineRects.erase(m_aLineRects.begin() + i);
858 --i;
859 break;
860 }
861 }
862 }
863 }
864 }
865}
866
867void SwLineRects::LockLines( bool bLock )
868{
869 for (SwLineRect& rLRect : m_aLineRects)
870 rLRect.Lock(bLock);
871}
872
873static void lcl_DrawDashedRect( OutputDevice * pOut, SwLineRect const & rLRect )
874{
875 tools::Long startX = rLRect.Left( ), endX;
876 tools::Long startY = rLRect.Top( ), endY;
877
878 // Discriminate vertically stretched rect from horizontally stretched
879 // and restrict minimum nHalfLWidth to 1
880 tools::Long nHalfLWidth = std::max( std::min( rLRect.Width( ), rLRect.Height( ) ) / 2, tools::Long(1) );
881
882 if ( rLRect.Height( ) > rLRect.Width( ) )
883 {
884 startX += nHalfLWidth;
885 endX = startX;
886 endY = startY + rLRect.Height( );
887 }
888 else
889 {
890 startY += nHalfLWidth;
891 endY = startY;
892 endX = startX + rLRect.Width( );
893 }
894
895 svtools::DrawLine( *pOut, Point( startX, startY ), Point( endX, endY ),
896 sal_uInt32( nHalfLWidth * 2 ), rLRect.GetStyle( ) );
897}
898
899void SwLineRects::PaintLines( OutputDevice *pOut, SwPaintProperties const &properties )
900{
901 // Paint the borders. Sadly two passes are needed.
902 // Once for the inside and once for the outside edges of tables
903 if (m_aLineRects.size() == m_nLastCount)
904 return;
905
906 // #i16816# tagged pdf support
907 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pOut );
908
910 pOut->SetFillColor();
911 pOut->SetLineColor();
912 ConnectEdges( pOut, properties );
913 const Color *pLast = nullptr;
914
915 bool bPaint2nd = false;
916 size_t nMinCount = m_aLineRects.size();
917
918 for (size_t i = 0; i < m_aLineRects.size(); ++i)
919 {
920 SwLineRect& rLRect = m_aLineRects[i];
921
922 if ( rLRect.IsPainted() )
923 continue;
924
925 if ( rLRect.IsLocked() )
926 {
927 nMinCount = std::min( nMinCount, i );
928 continue;
929 }
930
931 // Paint it now or in the second pass?
932 bool bPaint = true;
933 if ( rLRect.GetTab() )
934 {
935 if ( rLRect.Height() > rLRect.Width() )
936 {
937 // Vertical edge, overlapping with the table edge?
938 SwTwips nLLeft = rLRect.Left() - 30,
939 nLRight = rLRect.Right() + 30,
940 nTLeft = rLRect.GetTab()->getFrameArea().Left() + rLRect.GetTab()->getFramePrintArea().Left(),
941 nTRight = rLRect.GetTab()->getFrameArea().Left() + rLRect.GetTab()->getFramePrintArea().Right();
942 if ( (nTLeft >= nLLeft && nTLeft <= nLRight) ||
943 (nTRight>= nLLeft && nTRight<= nLRight) )
944 bPaint = false;
945 }
946 else
947 {
948 // Horizontal edge, overlapping with the table edge?
949 SwTwips nLTop = rLRect.Top() - 30,
950 nLBottom = rLRect.Bottom() + 30,
951 nTTop = rLRect.GetTab()->getFrameArea().Top() + rLRect.GetTab()->getFramePrintArea().Top(),
952 nTBottom = rLRect.GetTab()->getFrameArea().Top() + rLRect.GetTab()->getFramePrintArea().Bottom();
953 if ( (nTTop >= nLTop && nTTop <= nLBottom) ||
954 (nTBottom >= nLTop && nTBottom <= nLBottom) )
955 bPaint = false;
956 }
957 }
958 if ( bPaint )
959 {
960 if ( !pLast || *pLast != rLRect.GetColor() )
961 {
962 pLast = &rLRect.GetColor();
963
964 DrawModeFlags nOldDrawMode = pOut->GetDrawMode();
965 if( properties.pSGlobalShell->GetWin() &&
967 pOut->SetDrawMode( DrawModeFlags::Default );
968
969 pOut->SetLineColor( *pLast );
970 pOut->SetFillColor( *pLast );
971 pOut->SetDrawMode( nOldDrawMode );
972 }
973
974 if( !rLRect.IsEmpty() )
975 lcl_DrawDashedRect( pOut, rLRect );
976 rLRect.SetPainted();
977 }
978 else
979 bPaint2nd = true;
980 }
981 if ( bPaint2nd )
982 {
983 for (size_t i = 0; i < m_aLineRects.size(); ++i)
984 {
985 SwLineRect& rLRect = m_aLineRects[i];
986 if ( rLRect.IsPainted() )
987 continue;
988
989 if ( rLRect.IsLocked() )
990 {
991 nMinCount = std::min( nMinCount, i );
992 continue;
993 }
994
995 if ( !pLast || *pLast != rLRect.GetColor() )
996 {
997 pLast = &rLRect.GetColor();
998
999 DrawModeFlags nOldDrawMode = pOut->GetDrawMode();
1000 if( properties.pSGlobalShell->GetWin() &&
1002 {
1003 pOut->SetDrawMode( DrawModeFlags::Default );
1004 }
1005
1006 pOut->SetFillColor( *pLast );
1007 pOut->SetDrawMode( nOldDrawMode );
1008 }
1009 if( !rLRect.IsEmpty() )
1010 lcl_DrawDashedRect( pOut, rLRect );
1011 rLRect.SetPainted();
1012 }
1013 }
1014 m_nLastCount = nMinCount;
1015 pOut->Pop();
1016
1017}
1018
1019void SwSubsRects::PaintSubsidiary( OutputDevice *pOut,
1020 const SwLineRects *pRects,
1021 SwPaintProperties const & properties )
1022{
1023 if (m_aLineRects.empty())
1024 return;
1025
1026 // #i16816# tagged pdf support
1027 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pOut );
1028
1029 // Remove all help line that are almost covered (tables)
1030 for (size_type i = 0; i != m_aLineRects.size(); ++i)
1031 {
1032 SwLineRect& rLi = m_aLineRects[i];
1033 const bool bVerticalSubs = rLi.Height() > rLi.Width();
1034
1035 for (size_type k = i + 1; k != m_aLineRects.size(); ++k)
1036 {
1037 SwLineRect& rLk = m_aLineRects[k];
1038 if ( rLi.SSize() == rLk.SSize() )
1039 {
1040 if ( bVerticalSubs == ( rLk.Height() > rLk.Width() ) )
1041 {
1042 if ( bVerticalSubs )
1043 {
1044 tools::Long nLi = rLi.Right();
1045 tools::Long nLk = rLk.Right();
1046 if ( rLi.Top() == rLk.Top() &&
1047 ((nLi < rLk.Left() && nLi+21 > rLk.Left()) ||
1048 (nLk < rLi.Left() && nLk+21 > rLi.Left())))
1049 {
1050 m_aLineRects.erase(m_aLineRects.begin() + i);
1051 // don't continue with inner loop any more:
1052 // the array may shrink!
1053 --i;
1054 break;
1055 }
1056 }
1057 else
1058 {
1059 tools::Long nLi = rLi.Bottom();
1060 tools::Long nLk = rLk.Bottom();
1061 if ( rLi.Left() == rLk.Left() &&
1062 ((nLi < rLk.Top() && nLi+21 > rLk.Top()) ||
1063 (nLk < rLi.Top() && nLk+21 > rLi.Top())))
1064 {
1065 m_aLineRects.erase(m_aLineRects.begin() + i);
1066 // don't continue with inner loop any more:
1067 // the array may shrink!
1068 --i;
1069 break;
1070 }
1071 }
1072 }
1073 }
1074 }
1075 }
1076
1077 if (pRects && (!pRects->m_aLineRects.empty()))
1078 RemoveSuperfluousSubsidiaryLines( *pRects, properties );
1079
1080 if (m_aLineRects.empty())
1081 return;
1082
1084 pOut->SetLineColor();
1085
1086 // Reset draw mode in high contrast mode in order to get fill color
1087 // set at output device. Recover draw mode after draw of lines.
1088 // Necessary for the subsidiary lines painted by the fly frames.
1089 DrawModeFlags nOldDrawMode = pOut->GetDrawMode();
1090 if( gProp.pSGlobalShell->GetWin() &&
1092 {
1093 pOut->SetDrawMode( DrawModeFlags::Default );
1094 }
1095
1096 for (SwLineRect& rLRect : m_aLineRects)
1097 {
1098 // Add condition <!rLRect.IsLocked()> to prevent paint of locked subsidiary lines.
1099 if ( !rLRect.IsPainted() &&
1100 !rLRect.IsLocked() )
1101 {
1102 const Color *pCol = nullptr;
1103 SwViewShell *pShell = properties.pSGlobalShell;
1104 const SwViewOption *pOpt = pShell->GetViewOptions();
1105 switch ( rLRect.GetSubColor() )
1106 {
1107 case SubColFlags::Page: pCol = &pOpt->GetDocBoundariesColor(); break;
1108 case SubColFlags::Fly: pCol = &pOpt->GetObjectBoundariesColor(); break;
1109 case SubColFlags::Tab: pCol = &pOpt->GetTableBoundariesColor(); break;
1110 case SubColFlags::Sect: pCol = &pOpt->GetSectionBoundColor(); break;
1111 }
1112
1113 if (pCol && pOut->GetFillColor() != *pCol)
1114 pOut->SetFillColor( *pCol );
1115 pOut->DrawRect( rLRect.SVRect() );
1116
1117 rLRect.SetPainted();
1118 }
1119 }
1120
1121 pOut->SetDrawMode( nOldDrawMode );
1122
1123 pOut->Pop();
1124}
1125
1126// Various functions that are use in this file.
1127
1135void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext* pRenderContext )
1136{
1137 if( !rRect.HasArea() )
1138 return;
1139
1140 // Make sure that view shell (parameter <pSh>) exists, if the output device
1141 // is taken from this view shell --> no output device, no alignment
1142 // Output device taken from view shell <pSh>, if <gProp.bSFlyMetafile> not set
1143 if ( !gProp.bSFlyMetafile && !pSh )
1144 {
1145 return;
1146 }
1147
1148 const vcl::RenderContext *pOut = gProp.bSFlyMetafile ?
1149 gProp.pSFlyMetafileOut.get() : pRenderContext;
1150
1151 // Hold original rectangle in pixel
1152 const tools::Rectangle aOrgPxRect = pOut->LogicToPixel( rRect.SVRect() );
1153 // Determine pixel-center rectangle in twip
1154 const SwRect aPxCenterRect( pOut->PixelToLogic( aOrgPxRect ) );
1155
1156 // Perform adjustments on pixel level.
1157 SwRect aAlignedPxRect( aOrgPxRect );
1158 if ( rRect.Top() > aPxCenterRect.Top() )
1159 {
1160 // 'leave pixel overlapping on top'
1161 aAlignedPxRect.AddTop( 1 );
1162 }
1163
1164 if ( rRect.Bottom() < aPxCenterRect.Bottom() )
1165 {
1166 // 'leave pixel overlapping on bottom'
1167 aAlignedPxRect.AddBottom( - 1 );
1168 }
1169
1170 if ( rRect.Left() > aPxCenterRect.Left() )
1171 {
1172 // 'leave pixel overlapping on left'
1173 aAlignedPxRect.AddLeft( 1 );
1174 }
1175
1176 if ( rRect.Right() < aPxCenterRect.Right() )
1177 {
1178 // 'leave pixel overlapping on right'
1179 aAlignedPxRect.AddRight( - 1 );
1180 }
1181
1182 // Consider negative width/height check, if aligned SwRect has negative width/height.
1183 // If Yes, adjust it to width/height = 0 twip.
1184 // NOTE: A SwRect with negative width/height can occur, if the width/height
1185 // of the given SwRect in twip was less than a pixel in twip and that
1186 // the alignment calculates that the aligned SwRect should not contain
1187 // the pixels the width/height is on.
1188 if ( aAlignedPxRect.Width() < 0 )
1189 {
1190 aAlignedPxRect.Width(0);
1191 }
1192 if ( aAlignedPxRect.Height() < 0 )
1193 {
1194 aAlignedPxRect.Height(0);
1195 }
1196 // Consider zero width/height for converting a rectangle from
1197 // pixel to logic it needs a width/height. Thus, set width/height
1198 // to one, if it's zero and correct this on the twip level after the conversion.
1199 bool bZeroWidth = false;
1200 if ( aAlignedPxRect.Width() == 0 )
1201 {
1202 aAlignedPxRect.Width(1);
1203 bZeroWidth = true;
1204 }
1205 bool bZeroHeight = false;
1206 if ( aAlignedPxRect.Height() == 0 )
1207 {
1208 aAlignedPxRect.Height(1);
1209 bZeroHeight = true;
1210 }
1211
1212 rRect = SwRect(pOut->PixelToLogic( aAlignedPxRect.SVRect() ));
1213
1214 // Consider zero width/height and adjust calculated aligned twip rectangle.
1215 // Reset width/height to zero; previous negative width/height haven't to be considered.
1216 if ( bZeroWidth )
1217 {
1218 rRect.Width(0);
1219 }
1220 if ( bZeroHeight )
1221 {
1222 rRect.Height(0);
1223 }
1224}
1225
1241void SwAlignGrfRect( SwRect *pGrfRect, const vcl::RenderContext &rOut )
1242{
1243 tools::Rectangle aPxRect = rOut.LogicToPixel( pGrfRect->SVRect() );
1244 pGrfRect->Pos( rOut.PixelToLogic( aPxRect.TopLeft() ) );
1245 pGrfRect->SSize( rOut.PixelToLogic( aPxRect.GetSize() ) );
1246}
1247
1248static tools::Long lcl_AlignWidth( const tools::Long nWidth, SwPaintProperties const & properties )
1249{
1250 if ( nWidth )
1251 {
1252 const tools::Long nW = nWidth % properties.nSPixelSzW;
1253
1254 if ( !nW || nW > properties.nSHalfPixelSzW )
1255 return std::max(tools::Long(1), nWidth - properties.nSHalfPixelSzW);
1256 }
1257 return nWidth;
1258}
1259
1260static tools::Long lcl_AlignHeight( const tools::Long nHeight, SwPaintProperties const & properties )
1261{
1262 if ( nHeight )
1263 {
1264 const tools::Long nH = nHeight % properties.nSPixelSzH;
1265
1266 if ( !nH || nH > properties.nSHalfPixelSzH )
1267 return std::max(tools::Long(1), nHeight - properties.nSHalfPixelSzH);
1268 }
1269 return nHeight;
1270}
1271
1275static void lcl_CalcBorderRect( SwRect &rRect, const SwFrame *pFrame,
1276 const SwBorderAttrs &rAttrs,
1277 const bool bShadow,
1278 SwPaintProperties const & properties)
1279{
1280 // Special handling for cell frames.
1281 // The printing area of a cell frame is completely enclosed in the frame area
1282 // and a cell frame has no shadow. Thus, for cell frames the calculated
1283 // area equals the frame area.
1284 // Notes: Borders of cell frames in R2L text direction will switch its side
1285 // - left border is painted on the right; right border on the left.
1286 // See <lcl_PaintLeftLine> and <lcl_PaintRightLine>.
1287 if( pFrame->IsSctFrame() )
1288 {
1289 rRect = pFrame->getFramePrintArea();
1290 rRect.Pos() += pFrame->getFrameArea().Pos();
1291 }
1292 else if ( pFrame->IsCellFrame() )
1293 rRect = pFrame->getFrameArea();
1294 else
1295 {
1296 rRect = pFrame->getFramePrintArea();
1297 rRect.Pos() += pFrame->getFrameArea().Pos();
1298
1299 SwRectFn fnRect = pFrame->IsVertical() ? ( pFrame->IsVertLR() ? (pFrame->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
1300
1301 const SvxBoxItem &rBox = rAttrs.GetBox();
1302 const bool bTop = 0 != (pFrame->*fnRect->fnGetTopMargin)();
1303 if ( bTop || rBox.GetTop() )
1304 {
1305 SwTwips nDiff = rBox.GetTop() ?
1306 rBox.CalcLineSpace( SvxBoxItemLine::TOP, /*bEvenIfNoLine=*/false, /*bAllowNegative=*/true ) :
1307 rBox.GetDistance( SvxBoxItemLine::TOP );
1308 if( nDiff )
1309 (rRect.*fnRect->fnSubTop)( nDiff );
1310 }
1311
1312 const bool bBottom = 0 != (pFrame->*fnRect->fnGetBottomMargin)();
1313 if ( bBottom )
1314 {
1315 SwTwips nDiff = 0;
1316 // #i29550#
1317 if ( pFrame->IsTabFrame() &&
1318 static_cast<const SwTabFrame*>(pFrame)->IsCollapsingBorders() )
1319 {
1320 // For collapsing borders, we have to add the height of
1321 // the height of the last line
1322 nDiff = static_cast<const SwTabFrame*>(pFrame)->GetBottomLineSize();
1323 }
1324 else
1325 {
1326 nDiff = rBox.GetBottom() ?
1327 rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM ) :
1328 rBox.GetDistance( SvxBoxItemLine::BOTTOM );
1329 }
1330 if( nDiff )
1331 (rRect.*fnRect->fnAddBottom)( nDiff );
1332 }
1333
1334 if ( rBox.GetLeft() )
1335 (rRect.*fnRect->fnSubLeft)( rBox.CalcLineSpace( SvxBoxItemLine::LEFT ) );
1336 else
1337 (rRect.*fnRect->fnSubLeft)( rBox.GetDistance( SvxBoxItemLine::LEFT ) );
1338
1339 if ( rBox.GetRight() )
1340 (rRect.*fnRect->fnAddRight)( rBox.CalcLineSpace( SvxBoxItemLine::RIGHT ) );
1341 else
1342 (rRect.*fnRect->fnAddRight)( rBox.GetDistance( SvxBoxItemLine::RIGHT ) );
1343
1344 if ( bShadow && rAttrs.GetShadow().GetLocation() != SvxShadowLocation::NONE )
1345 {
1346 const SvxShadowItem &rShadow = rAttrs.GetShadow();
1347 if ( bTop )
1348 (rRect.*fnRect->fnSubTop)(rShadow.CalcShadowSpace(SvxShadowItemSide::TOP));
1349 (rRect.*fnRect->fnSubLeft)(rShadow.CalcShadowSpace(SvxShadowItemSide::LEFT));
1350 if ( bBottom )
1351 (rRect.*fnRect->fnAddBottom)
1352 (rShadow.CalcShadowSpace( SvxShadowItemSide::BOTTOM ));
1353 (rRect.*fnRect->fnAddRight)(rShadow.CalcShadowSpace(SvxShadowItemSide::RIGHT));
1354 }
1355 }
1356
1357 ::SwAlignRect( rRect, properties.pSGlobalShell, properties.pSGlobalShell ? properties.pSGlobalShell->GetOut() : nullptr );
1358}
1359
1364static void lcl_ExtendLeftAndRight( SwRect& _rRect,
1365 const SwFrame& _rFrame,
1366 const SwBorderAttrs& _rAttrs,
1367 const SwRectFn& _rRectFn )
1368{
1369 if ( _rAttrs.JoinedWithPrev( _rFrame ) )
1370 {
1371 const SwFrame* pPrevFrame = _rFrame.GetPrev();
1372 (_rRect.*_rRectFn->fnSetTop)( (pPrevFrame->*_rRectFn->fnGetPrtBottom)() );
1373 }
1374 if ( _rAttrs.JoinedWithNext( _rFrame ) )
1375 {
1376 const SwFrame* pNextFrame = _rFrame.GetNext();
1377 (_rRect.*_rRectFn->fnSetBottom)( (pNextFrame->*_rRectFn->fnGetPrtTop)() );
1378 }
1379}
1380
1384{
1385 static MapMode aMapMode(MapUnit::MapTwip);
1386 static const Size aSingleUnit = Application::GetDefaultDevice()->PixelToLogic(Size(1, 1), aMapMode);
1387
1388 double x1 = rRect.Left() + aSingleUnit.getWidth();
1389 double y1 = rRect.Top() + aSingleUnit.getHeight();
1390 double x2 = rRect.Right() - aSingleUnit.getWidth();
1391 double y2 = rRect.Bottom() - aSingleUnit.getHeight();
1392
1393 return basegfx::B2DRange(x1, y1, x2, y2);
1394}
1395
1396static void lcl_SubtractFlys( const SwFrame *pFrame, const SwPageFrame *pPage,
1397 const SwRect &rRect, SwRegionRects &rRegion, basegfx::utils::B2DClipState& rClipState, SwPaintProperties const & rProperties)
1398{
1399 const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
1400 const SwFlyFrame* pSelfFly = pFrame->IsInFly() ? pFrame->FindFlyFrame() : gProp.pSRetoucheFly2;
1401 if (!gProp.pSRetoucheFly)
1402 gProp.pSRetoucheFly = gProp.pSRetoucheFly2;
1403
1404 for (size_t j = 0; (j < rObjs.size()) && !rRegion.empty(); ++j)
1405 {
1406 const SwAnchoredObject* pAnchoredObj = rObjs[j];
1407 const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
1408
1409 // Do not consider invisible objects
1411 continue;
1412
1413 const SwFlyFrame *pFly = pAnchoredObj->DynCastFlyFrame();
1414 if (!pFly)
1415 continue;
1416
1417 if (pSelfFly == pFly || gProp.pSRetoucheFly == pFly || !rRect.Overlaps(pFly->getFrameArea()))
1418 continue;
1419
1420 if (!pFly->GetFormat()->GetPrint().GetValue() &&
1421 (OUTDEV_PRINTER == gProp.pSGlobalShell->GetOut()->GetOutDevType() ||
1422 gProp.pSGlobalShell->IsPreview()))
1423 continue;
1424
1425 const bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly );
1426
1427 //For character bound Flys only examine those Flys in which it is not
1428 //anchored itself.
1429 //Why only for character bound ones you may ask? It never makes sense to
1430 //subtract frames in which it is anchored itself right?
1431 if (pSelfFly && pSelfFly->IsLowerOf(pFly))
1432 continue;
1433
1434 //Any why does it not apply for the RetoucheFly too?
1435 if (gProp.pSRetoucheFly && gProp.pSRetoucheFly->IsLowerOf(pFly))
1436 continue;
1437
1438#if OSL_DEBUG_LEVEL > 0
1439 //Flys who are anchored inside their own one, must have a bigger OrdNum
1440 //or be character bound.
1441 if (pSelfFly && bLowerOfSelf)
1442 {
1443 OSL_ENSURE( pFly->IsFlyInContentFrame() ||
1444 pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
1445 "Fly with wrong z-Order" );
1446 }
1447#endif
1448
1449 bool bStopOnHell = true;
1450 if (pSelfFly)
1451 {
1452 const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
1453 if (pSdrObj->GetLayer() == pTmp->GetLayer())
1454 {
1455 if (pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect())
1456 //In the same layer we only observe those that are above.
1457 continue;
1458 }
1459 else
1460 {
1461 if (!bLowerOfSelf && !pFly->GetFormat()->GetOpaque().GetValue())
1462 //From other layers we are only interested in non
1463 //transparent ones or those that are internal
1464 continue;
1465 bStopOnHell = false;
1466 }
1467 }
1468 if (gProp.pSRetoucheFly)
1469 {
1470 const SdrObject *pTmp = gProp.pSRetoucheFly->GetVirtDrawObj();
1471 if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
1472 {
1473 if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
1474 //In the same layer we only observe those that are above.
1475 continue;
1476 }
1477 else
1478 {
1479 if (!pFly->IsLowerOf( gProp.pSRetoucheFly ) && !pFly->GetFormat()->GetOpaque().GetValue())
1480 //From other layers we are only interested in non
1481 //transparent ones or those that are internal
1482 continue;
1483 bStopOnHell = false;
1484 }
1485 }
1486
1487 //If the content of the Fly is transparent, we subtract it only if it's
1488 //contained in the hell layer.
1490 bool bHell = pSdrObj->GetLayer() == rIDDMA.GetHellId();
1491 if ( (bStopOnHell && bHell) ||
1495 ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTextFrame() &&
1496 (static_cast<SwNoTextFrame const*>(pFly->Lower())->IsTransparent() ||
1497 static_cast<SwNoTextFrame const*>(pFly->Lower())->HasAnimation() ||
1498 pFly->GetFormat()->GetSurround().IsContour()
1499 )
1500 )
1501 )
1502 continue;
1503
1504 // Own if-statements for transparent background/shadow of fly frames
1505 // in order to handle special conditions.
1506 if (pFly->IsBackgroundTransparent())
1507 {
1508 // Background <pFly> is transparent drawn. Thus normally, its region
1509 // have not to be subtracted from given region.
1510 // But, if method is called for a fly frame and
1511 // <pFly> is a direct lower of this fly frame and
1512 // <pFly> inherites its transparent background brush from its parent,
1513 // then <pFly> frame area have to be subtracted from given region.
1514 // NOTE: Because in Status Quo transparent backgrounds can only be
1515 // assigned to fly frames, the handle of this special case
1516 // avoids drawing of transparent areas more than once, if
1517 // a fly frame inherites a transparent background from its
1518 // parent fly frame.
1519 if (pFrame->IsFlyFrame() &&
1520 (pFly->GetAnchorFrame()->FindFlyFrame() == pFrame) &&
1522 )
1523 {
1524 SwRect aRect;
1525 SwBorderAttrAccess aAccess( SwFrame::GetCache(), static_cast<SwFrame const *>(pFly) );
1526 const SwBorderAttrs &rAttrs = *aAccess.Get();
1527 ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true, rProperties );
1528 rRegion -= aRect;
1529 rClipState.subtractRange(lcl_ShrinkFly(aRect));
1530 continue;
1531 }
1532 else
1533 {
1534 continue;
1535 }
1536 }
1537
1538 if (bHell && pFly->GetAnchorFrame()->IsInFly())
1539 {
1540 //So the border won't get dismantled by the background of the other
1541 //Fly.
1542 SwRect aRect;
1543 SwBorderAttrAccess aAccess( SwFrame::GetCache(), static_cast<SwFrame const *>(pFly) );
1544 const SwBorderAttrs &rAttrs = *aAccess.Get();
1545 ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true, rProperties );
1546 rRegion -= aRect;
1547 rClipState.subtractRange(lcl_ShrinkFly(aRect));
1548 }
1549 else
1550 {
1551 SwRect aRect( pFly->getFramePrintArea() );
1552 aRect += pFly->getFrameArea().Pos();
1553 rRegion -= aRect;
1554 rClipState.subtractRange(lcl_ShrinkFly(aRect));
1555 }
1556 }
1557 if (gProp.pSRetoucheFly == gProp.pSRetoucheFly2)
1558 gProp.pSRetoucheFly = nullptr;
1559}
1560
1561static void lcl_implDrawGraphicBackground(const SvxBrushItem& _rBackgrdBrush,
1562 vcl::RenderContext& _rOut,
1563 const SwRect& _rAlignedPaintRect,
1564 const GraphicObject& _rGraphicObj,
1565 SwPaintProperties const & properties)
1566{
1571 const Color aColor( ( (_rBackgrdBrush.GetColor() != COL_TRANSPARENT) || properties.bSFlyMetafile )
1572 ? _rBackgrdBrush.GetColor()
1574
1577 sal_Int8 nTransparencyPercent = 0;
1578 bool bDrawTransparent = false;
1579 if ( aColor.IsTransparent() )
1581 {
1582 bDrawTransparent = true;
1583 nTransparencyPercent = ((255 - aColor.GetAlpha())*100 + 0x7F)/0xFF;
1584 }
1585 else if ( (_rGraphicObj.GetAttr().IsTransparent()) &&
1586 (_rBackgrdBrush.GetColor() == COL_TRANSPARENT) )
1589 {
1590 bDrawTransparent = true;
1591 nTransparencyPercent = 100 - (_rGraphicObj.GetAttr().GetAlpha() * 100 + 127) / 255;
1592 }
1593
1594 if ( bDrawTransparent )
1595 {
1597 if( _rOut.GetFillColor() != aColor.GetRGBColor() )
1598 _rOut.SetFillColor( aColor.GetRGBColor() );
1599 tools::PolyPolygon aPoly( _rAlignedPaintRect.SVRect() );
1600 _rOut.DrawTransparent( aPoly, nTransparencyPercent );
1601 }
1602 else
1603 {
1605 if ( _rOut.GetFillColor() != aColor )
1606 _rOut.SetFillColor( aColor );
1607 _rOut.DrawRect( _rAlignedPaintRect.SVRect() );
1608 }
1609}
1610
1643static void lcl_DrawGraphicBackground( const SvxBrushItem& _rBackgrdBrush,
1644 OutputDevice& _rOut,
1645 const SwRect& _rAlignedPaintRect,
1646 const GraphicObject& _rGraphicObj,
1647 bool _bNumberingGraphic,
1648 SwPaintProperties const & properties,
1649 bool _bBackgrdAlreadyDrawn = false)
1650{
1651 // draw background with background color, if
1652 // (1) graphic is not used as a numbering AND
1653 // (2) background is not already drawn AND
1654 // (3) intrinsic graphic is transparent OR intrinsic graphic doesn't exists
1655 if ( !_bNumberingGraphic &&
1656 !_bBackgrdAlreadyDrawn &&
1657 ( _rGraphicObj.IsTransparent() || _rGraphicObj.GetType() == GraphicType::NONE )
1658 )
1659 {
1660 lcl_implDrawGraphicBackground( _rBackgrdBrush, _rOut, _rAlignedPaintRect, _rGraphicObj, properties );
1661 }
1662}
1663
1679static void lcl_DrawGraphic( const SvxBrushItem& rBrush, vcl::RenderContext &rOutDev,
1680 const SwViewShell &rSh, const SwRect &rGrf, const SwRect &rOut,
1681 bool bGrfNum,
1682 SwPaintProperties const & properties,
1683 bool bBackgrdAlreadyDrawn )
1684 // add parameter <bBackgrdAlreadyDrawn> to indicate
1685 // that the background is already drawn.
1686{
1687 // Calculate align rectangle from parameter <rGrf> and use aligned
1688 // rectangle <aAlignedGrfRect> in the following code
1689 SwRect aAlignedGrfRect = rGrf;
1690 ::SwAlignRect( aAlignedGrfRect, &rSh, &rOutDev );
1691
1692 // Change type from <bool> to <bool>.
1693 const bool bNotInside = !rOut.Contains( aAlignedGrfRect );
1694 if ( bNotInside )
1695 {
1697 rOutDev.IntersectClipRegion( rOut.SVRect() );
1698 }
1699
1700 GraphicObject *pGrf = const_cast<GraphicObject*>(rBrush.GetGraphicObject());
1701
1702 OUString aOriginURL = pGrf->GetGraphic().getOriginURL();
1703 if (pGrf->GetGraphic().GetType() == GraphicType::Default && !aOriginURL.isEmpty())
1704 {
1705 Graphic aGraphic = vcl::graphic::loadFromURL(aOriginURL);
1706 pGrf->SetGraphic(aGraphic);
1707 }
1708
1709 // Outsource drawing of background with a background color
1710 ::lcl_DrawGraphicBackground( rBrush, rOutDev, aAlignedGrfRect, *pGrf, bGrfNum, properties, bBackgrdAlreadyDrawn );
1711
1712 // Because for drawing a graphic left-top-corner and size coordinates are
1713 // used, these coordinates have to be determined on pixel level.
1714 ::SwAlignGrfRect( &aAlignedGrfRect, rOutDev );
1715
1716 const basegfx::B2DHomMatrix aGraphicTransform(
1718 aAlignedGrfRect.Width(), aAlignedGrfRect.Height(),
1719 aAlignedGrfRect.Left(), aAlignedGrfRect.Top()));
1720
1722 rOutDev,
1723 *pGrf,
1724 pGrf->GetAttr(),
1725 aGraphicTransform,
1726 OUString(),
1727 OUString(),
1728 OUString());
1729
1730 if ( bNotInside )
1731 rOutDev.Pop();
1732}
1733
1736 const SwRect& rOriginalLayoutRect,
1737 const SwRegionRects& rPaintRegion,
1738 const basegfx::utils::B2DClipState& rClipState,
1739 vcl::RenderContext& rOut)
1740{
1741 if(rFillAttributes && rFillAttributes->isUsed())
1742 {
1743 basegfx::B2DRange aPaintRange(
1744 rPaintRegion.GetOrigin().Left(),
1745 rPaintRegion.GetOrigin().Top(),
1746 rPaintRegion.GetOrigin().Right(),
1747 rPaintRegion.GetOrigin().Bottom());
1748
1749 if (!aPaintRange.isEmpty() &&
1750 !rPaintRegion.empty() &&
1751 !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
1752 !basegfx::fTools::equalZero(aPaintRange.getHeight()))
1753 {
1754 // need to expand for correct AAed and non-AAed visualization as primitive.
1755 // This must probably be removed again when we will be able to get all Writer visualization
1756 // as primitives and Writer prepares all it's stuff in high precision coordinates (also
1757 // needs to avoid moving boundaries around to better show overlapping stuff...)
1759 {
1760 // if AAed in principle expand by 0.5 in all directions. Since painting edges of
1761 // AAed regions does not add to no transparence (0.5 opacity covered by 0.5 opacity
1762 // is not full opacity but 0.75 opacity) we need some overlap here to avoid paint
1763 // artifacts. Checked experimentally - a little bit more in Y is needed, probably
1764 // due to still existing integer alignment and crunching in writer.
1765 static const double fExpandX = 0.55;
1766 static const double fExpandY = 0.70;
1767 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(fExpandX, fExpandY));
1768
1769 aPaintRange.expand(aPaintRange.getMinimum() - aSingleUnit);
1770 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit);
1771 }
1772 else
1773 {
1774 // if not AAed expand by one unit to bottom right due to the missing unit
1775 // from SwRect/Rectangle integer handling
1776 const basegfx::B2DVector aSingleUnit(rOut.GetInverseViewTransformation() * basegfx::B2DVector(1.0, 1.0));
1777
1778 aPaintRange.expand(aPaintRange.getMaximum() + aSingleUnit);
1779 }
1780
1781 const basegfx::B2DRange aDefineRange(
1782 rOriginalLayoutRect.Left(),
1783 rOriginalLayoutRect.Top(),
1784 rOriginalLayoutRect.Right(),
1785 rOriginalLayoutRect.Bottom());
1786
1787 const drawinglayer::primitive2d::Primitive2DContainer& rSequence = rFillAttributes->getPrimitive2DSequence(
1788 aPaintRange,
1789 aDefineRange);
1790
1791 if(rSequence.size())
1792 {
1794 pPrimitives(&rSequence);
1796 // tdf#86578 the awful lcl_SubtractFlys hack
1797 if (rPaintRegion.size() > 1 || rPaintRegion[0] != rPaintRegion.GetOrigin())
1798 {
1799 basegfx::B2DPolyPolygon const& maskRegion(rClipState.getClipPoly());
1800 primitives.resize(1);
1803 pPrimitives = &primitives;
1804 }
1805 assert(pPrimitives && pPrimitives->size());
1806
1808 aViewInformation2D.setViewTransformation(rOut.GetViewTransformation());
1809 aViewInformation2D.setViewport(aPaintRange);
1810
1811 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(drawinglayer::processor2d::createProcessor2DFromOutputDevice(
1812 rOut,
1813 aViewInformation2D) );
1814 pProcessor->process(*pPrimitives);
1815 return true;
1816 }
1817 }
1818 }
1819
1820 return false;
1821}
1822
1824 const SvxBrushItem *pBrush,
1825 vcl::RenderContext &rOutDev,
1826 const SwRect &rOrg,
1827 const SwRect &rOut,
1828 const sal_uInt8 nGrfNum,
1829 const bool bConsiderBackgroundTransparency )
1830 // Add 6th parameter to indicate that method should
1831 // consider background transparency, saved in the color of the brush item
1832{
1833 SwViewShell &rSh = *gProp.pSGlobalShell;
1834 bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
1835 bool bGrfNum = GRFNUM_NO != nGrfNum;
1836 Size aGrfSize;
1838 if( pBrush && !bReplaceGrfNum )
1839 {
1840 if( rSh.GetViewOptions()->IsGraphic() )
1841 {
1842 OUString referer;
1843 SfxObjectShell * sh = rSh.GetDoc()->GetPersist();
1844 if (sh != nullptr && sh->HasName()) {
1845 referer = sh->GetMedium()->GetName();
1846 }
1847 const Graphic* pGrf = pBrush->GetGraphic(referer);
1848 if( pGrf && GraphicType::NONE != pGrf->GetType() )
1849 {
1850 ePos = pBrush->GetGraphicPos();
1851 if( pGrf->IsSupportedGraphic() )
1852 // don't the use the specific output device! Bug 94802
1853 aGrfSize = ::GetGraphicSizeTwip( *pGrf, nullptr );
1854 }
1855 }
1856 else
1857 bReplaceGrfNum = bGrfNum;
1858 }
1859
1860 SwRect aGrf;
1861 aGrf.SSize( aGrfSize );
1862 bool bDraw = true;
1863 bool bRetouche = true;
1864 switch ( ePos )
1865 {
1866 case GPOS_LT:
1867 aGrf.Pos() = rOrg.Pos();
1868 break;
1869
1870 case GPOS_MT:
1871 aGrf.Pos().setY( rOrg.Top() );
1872 aGrf.Pos().setX( rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2 );
1873 break;
1874
1875 case GPOS_RT:
1876 aGrf.Pos().setY( rOrg.Top() );
1877 aGrf.Pos().setX( rOrg.Right() - aGrfSize.Width() );
1878 break;
1879
1880 case GPOS_LM:
1881 aGrf.Pos().setY( rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2 );
1882 aGrf.Pos().setX( rOrg.Left() );
1883 break;
1884
1885 case GPOS_MM:
1886 aGrf.Pos().setY( rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2 );
1887 aGrf.Pos().setX( rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2 );
1888 break;
1889
1890 case GPOS_RM:
1891 aGrf.Pos().setY( rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2 );
1892 aGrf.Pos().setX( rOrg.Right() - aGrfSize.Width() );
1893 break;
1894
1895 case GPOS_LB:
1896 aGrf.Pos().setY( rOrg.Bottom() - aGrfSize.Height() );
1897 aGrf.Pos().setX( rOrg.Left() );
1898 break;
1899
1900 case GPOS_MB:
1901 aGrf.Pos().setY( rOrg.Bottom() - aGrfSize.Height() );
1902 aGrf.Pos().setX( rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2 );
1903 break;
1904
1905 case GPOS_RB:
1906 aGrf.Pos().setY( rOrg.Bottom() - aGrfSize.Height() );
1907 aGrf.Pos().setX( rOrg.Right() - aGrfSize.Width() );
1908 break;
1909
1910 case GPOS_AREA:
1911 aGrf = rOrg;
1912 // Despite the fact that the background graphic has to fill the complete
1913 // area, we already checked, whether the graphic will completely fill out
1914 // the region the <rOut> that is to be painted. Thus, nothing has to be
1915 // touched again.
1916 // E.g. this is the case for a Fly Frame without a background
1917 // brush positioned on the border of the page which inherited the background
1918 // brush from the page.
1919 bRetouche = !rOut.Contains( aGrf );
1920 break;
1921
1922 case GPOS_TILED:
1923 {
1924 // draw background of tiled graphic before drawing tiled graphic in loop
1925 // determine graphic object
1926 GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject());
1927 // calculate aligned paint rectangle
1928 SwRect aAlignedPaintRect = rOut;
1929 ::SwAlignRect( aAlignedPaintRect, &rSh, &rOutDev );
1930 // draw background color for aligned paint rectangle
1931 lcl_DrawGraphicBackground( *pBrush, rOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum, gProp );
1932
1933 // set left-top-corner of background graphic to left-top-corner of the
1934 // area, from which the background brush is determined.
1935 aGrf.Pos() = rOrg.Pos();
1936 // setup clipping at output device
1938 rOutDev.IntersectClipRegion( rOut.SVRect() );
1939 // use new method <GraphicObject::DrawTiled(::)>
1940 {
1941 // calculate paint offset
1942 Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() );
1943 // draw background graphic tiled for aligned paint rectangle
1944 // #i42643#
1945 // For PDF export, every draw operation for bitmaps takes a
1946 // noticeable amount of place (~50 characters). Thus, optimize
1947 // between tile bitmap size and number of drawing operations here.
1948
1949 // A_out
1950 // n_chars = k1 * ---------- + k2 * A_bitmap
1951 // A_bitmap
1952
1953 // minimum n_chars is obtained for (derive for A_bitmap,
1954 // set to 0, take positive solution):
1955 // k1
1956 // A_bitmap = Sqrt( ---- A_out )
1957 // k2
1958
1959 // where k1 is the number of chars per draw operation, and
1960 // k2 is the number of chars per bitmap pixel.
1961 // This is approximately 50 and 7 for current PDF writer, respectively.
1962
1963 const double k1( 50 );
1964 const double k2( 7 );
1965 const Size aSize( aAlignedPaintRect.SSize() );
1966 const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() );
1967
1968 pGraphicObj->DrawTiled( rOutDev,
1969 aAlignedPaintRect.SVRect(),
1970 aGrf.SSize(),
1971 Size( aPaintOffset.X(), aPaintOffset.Y() ),
1972 std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1973 }
1974 // reset clipping at output device
1975 rOutDev.Pop();
1976 // set <bDraw> and <bRetouche> to false, indicating that background
1977 // graphic and background are already drawn.
1978 bDraw = bRetouche = false;
1979 }
1980 break;
1981
1982 case GPOS_NONE:
1983 bDraw = false;
1984 break;
1985
1986 default: OSL_ENSURE( false, "new Graphic position?" );
1987 }
1988
1991 bool bGrfBackgrdAlreadyDrawn = false;
1992 if ( bRetouche )
1993 {
1995 rOutDev.SetLineColor();
1996
1997 // check, if an existing background graphic (not filling the complete
1998 // background) is transparent drawn and the background color is
1999 // "no fill" respectively "auto fill", if background transparency
2000 // has to be considered.
2001 // If YES, memorize transparency of background graphic.
2002 // check also, if background graphic bitmap is transparent.
2003 bool bTransparentGrfWithNoFillBackgrd = false;
2004 sal_Int32 nGrfTransparency = 0;
2005 bool bGrfIsTransparent = false;
2006 if ( (ePos != GPOS_NONE) &&
2007 (ePos != GPOS_TILED) && (ePos != GPOS_AREA)
2008 )
2009 {
2010 GraphicObject *pGrf = const_cast<GraphicObject*>(pBrush->GetGraphicObject());
2011 if ( bConsiderBackgroundTransparency )
2012 {
2013 GraphicAttr aGrfAttr = pGrf->GetAttr();
2014 if ( (aGrfAttr.IsTransparent()) &&
2015 (pBrush->GetColor() == COL_TRANSPARENT)
2016 )
2017 {
2018 bTransparentGrfWithNoFillBackgrd = true;
2019 nGrfTransparency = 255 - aGrfAttr.GetAlpha();
2020 }
2021 }
2022 if ( pGrf->IsTransparent() )
2023 {
2024 bGrfIsTransparent = true;
2025 }
2026 }
2027
2028 // to get color of brush, check background color against COL_TRANSPARENT ("no fill"/"auto fill")
2029 // instead of checking, if transparency is not set.
2030 const Color aColor( pBrush &&
2031 ( (pBrush->GetColor() != COL_TRANSPARENT) ||
2032 gProp.bSFlyMetafile )
2033 ? pBrush->GetColor()
2035
2036 // determine, if background region have to be
2037 // drawn transparent.
2038 // background region has to be drawn transparent, if
2039 // background transparency have to be considered
2040 // AND
2041 // ( background color is transparent OR
2042 // background graphic is transparent and background color is "no fill"
2043 // )
2044
2045 enum DrawStyle {
2046 Default,
2048 } eDrawStyle = Default;
2049
2050 if (bConsiderBackgroundTransparency &&
2051 ( ( aColor.IsTransparent()) ||
2052 bTransparentGrfWithNoFillBackgrd ) )
2053 {
2054 eDrawStyle = Transparent;
2055 }
2056
2057 // #i75614# reset draw mode in high contrast mode in order to get fill color set
2058 const DrawModeFlags nOldDrawMode = rOutDev.GetDrawMode();
2059 if ( gProp.pSGlobalShell->GetWin() &&
2061 {
2062 rOutDev.SetDrawMode( DrawModeFlags::Default );
2063 }
2064
2065 // If background region has to be drawn transparent, set only the RGB values of the background color as
2066 // the fill color for the output device.
2067 switch (eDrawStyle)
2068 {
2069 case Transparent:
2070 {
2071 if( rOutDev.GetFillColor() != aColor.GetRGBColor() )
2072 rOutDev.SetFillColor( aColor.GetRGBColor() );
2073 break;
2074 }
2075 default:
2076 {
2077 if( rOutDev.GetFillColor() != aColor )
2078 rOutDev.SetFillColor( aColor );
2079 break;
2080 }
2081 }
2082
2083 // #i75614#
2084 // restore draw mode
2085 rOutDev.SetDrawMode( nOldDrawMode );
2086
2087 switch (eDrawStyle)
2088 {
2089 case Transparent:
2090 {
2091 // background region have to be drawn transparent.
2092 // Thus, create a poly-polygon from the region and draw it with
2093 // the corresponding transparency percent.
2094 tools::PolyPolygon aDrawPoly( rOut.SVRect() );
2095 if ( aGrf.HasArea() )
2096 {
2097 if ( !bGrfIsTransparent )
2098 {
2099 // subtract area of background graphic from draw area
2100 // Consider only that part of the graphic area that is overlapping with draw area.
2101 SwRect aTmpGrf = aGrf;
2102 aTmpGrf.Intersection( rOut );
2103 if ( aTmpGrf.HasArea() )
2104 {
2105 tools::Polygon aGrfPoly( aTmpGrf.SVRect() );
2106 aDrawPoly.Insert( aGrfPoly );
2107 }
2108 }
2109 else
2110 bGrfBackgrdAlreadyDrawn = true;
2111 }
2112 // calculate transparency percent:
2113 // ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF
2114 // If there is a background graphic with a background color "no fill"/"auto fill",
2115 // the transparency value is taken from the background graphic,
2116 // otherwise take the transparency value from the color.
2117 sal_Int8 nTransparencyPercent = static_cast<sal_Int8>(
2118 (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : (255 - aColor.GetAlpha())
2119 )*100 + 0x7F)/0xFF);
2120 // draw poly-polygon transparent
2121 rOutDev.DrawTransparent( aDrawPoly, nTransparencyPercent );
2122
2123 break;
2124 }
2125 case Default:
2126 default:
2127 {
2128 SwRegionRects aRegion( rOut, 4 );
2129 if ( !bGrfIsTransparent )
2130 aRegion -= aGrf;
2131 else
2132 bGrfBackgrdAlreadyDrawn = true;
2133 // loop rectangles of background region, which has to be drawn
2134 for( size_t i = 0; i < aRegion.size(); ++i )
2135 {
2136 rOutDev.DrawRect( aRegion[i].SVRect() );
2137 }
2138 }
2139 }
2140 rOutDev.Pop();
2141 }
2142
2143 if( bDraw && aGrf.Overlaps( rOut ) )
2144 lcl_DrawGraphic( *pBrush, rOutDev, rSh, aGrf, rOut, bGrfNum, gProp,
2145 bGrfBackgrdAlreadyDrawn );
2146
2147 if( bReplaceGrfNum )
2148 {
2149 const BitmapEx& rBmp = rSh.GetReplacementBitmap(false);
2150 vcl::Font aTmp( rOutDev.GetFont() );
2151 Graphic::DrawEx(rOutDev, OUString(), aTmp, rBmp, rOrg.Pos(), rOrg.SSize());
2152 }
2153}
2154
2163static void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const vcl::RenderContext &aOut )
2164{
2165 // local constant object of class <Size> to determine number of Twips
2166 // representing a pixel.
2167 const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) );
2168
2169 // local object of class <Rectangle> in Twip coordinates
2170 // calculated from given rectangle aligned to pixel centers.
2171 const tools::Rectangle aPxCenterRect = aOut.PixelToLogic(
2172 aOut.LogicToPixel( io_aSwRect.SVRect() ) );
2173
2174 // local constant object of class <Rectangle> representing given rectangle
2175 // in pixel.
2176 const tools::Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2177
2178 // calculate adjusted rectangle from pixel centered rectangle.
2179 // Due to rounding differences <aPxCenterRect> doesn't exactly represents
2180 // the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1.
2181 // Afterwards, adjust calculated Twip-positions of the all borders.
2182 tools::Rectangle aSizedRect = aPxCenterRect;
2183 aSizedRect.AdjustLeft( -(aTwipToPxSize.Width()/2 + 1) );
2184 aSizedRect.AdjustRight( aTwipToPxSize.Width()/2 + 1 );
2185 aSizedRect.AdjustTop( -(aTwipToPxSize.Height()/2 + 1) );
2186 aSizedRect.AdjustBottom(aTwipToPxSize.Height()/2 + 1);
2187
2188 // adjust left()
2189 while ( aOut.LogicToPixel(aSizedRect).Left() < aOrgPxRect.Left() )
2190 {
2191 aSizedRect.AdjustLeft( 1 );
2192 }
2193 // adjust right()
2194 while ( aOut.LogicToPixel(aSizedRect).Right() > aOrgPxRect.Right() )
2195 {
2196 aSizedRect.AdjustRight( -1 );
2197 }
2198 // adjust top()
2199 while ( aOut.LogicToPixel(aSizedRect).Top() < aOrgPxRect.Top() )
2200 {
2201 aSizedRect.AdjustTop( 1 );
2202 }
2203 // adjust bottom()
2204 while ( aOut.LogicToPixel(aSizedRect).Bottom() > aOrgPxRect.Bottom() )
2205 {
2206 aSizedRect.AdjustBottom( -1 );
2207 }
2208
2209 io_aSwRect = SwRect( aSizedRect );
2210
2211#if OSL_DEBUG_LEVEL > 0
2212 tools::Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
2213 tools::Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2214 OSL_ENSURE( aTestOrgPxRect == aTestNewPxRect,
2215 "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size");
2216 // check Left()
2217 aSizedRect.AdjustLeft( -1 );
2218 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2219 OSL_ENSURE( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1),
2220 "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted");
2221 aSizedRect.AdjustLeft( 1 );
2222 // check Right()
2223 aSizedRect.AdjustRight( 1 );
2224 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2225 OSL_ENSURE( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1),
2226 "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted");
2227 aSizedRect.AdjustRight( -1 );
2228 // check Top()
2229 aSizedRect.AdjustTop( -1 );
2230 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2231 OSL_ENSURE( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1),
2232 "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted");
2233 aSizedRect.AdjustTop( 1 );
2234 // check Bottom()
2235 aSizedRect.AdjustBottom( 1 );
2236 aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
2237 OSL_ENSURE( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1),
2238 "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted");
2239 aSizedRect.AdjustBottom( -1 );
2240#endif
2241}
2242
2243// FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START
2244
2245namespace {
2246
2247struct SwLineEntry
2248{
2249 SwTwips mnKey;
2250 SwTwips mnStartPos;
2251 SwTwips mnEndPos;
2252 SwTwips mnLimitedEndPos;
2253 bool mbOuter;
2254
2255 svx::frame::Style maAttribute;
2256
2257 enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 };
2258
2259 enum class VerticalType { LEFT, RIGHT };
2260
2261public:
2262 SwLineEntry( SwTwips nKey,
2263 SwTwips nStartPos,
2264 SwTwips nEndPos,
2265 bool bOuter,
2266 const svx::frame::Style& rAttribute );
2267
2268 OverlapType Overlaps( const SwLineEntry& rComp ) const;
2269
2274 void LimitVerticalEndPos(const SwFrame& rFrame, VerticalType eType);
2275};
2276
2277}
2278
2279SwLineEntry::SwLineEntry( SwTwips nKey,
2280 SwTwips nStartPos,
2281 SwTwips nEndPos,
2282 bool bOuter,
2283 const svx::frame::Style& rAttribute )
2284 : mnKey( nKey ),
2285 mnStartPos( nStartPos ),
2286 mnEndPos( nEndPos ),
2287 mnLimitedEndPos(0),
2288 mbOuter(bOuter),
2289 maAttribute( rAttribute )
2290{
2291}
2292
2293/*
2294
2295 1. ---------- rOld
2296 ---------- rNew
2297
2298 2. ---------- rOld
2299 ------------- rNew
2300
2301 3. ------- rOld
2302 ------------- rNew
2303
2304 4. ------------- rOld
2305 ---------- rNew
2306
2307 5. ---------- rOld
2308 ---- rNew
2309
2310 6. ---------- rOld
2311 ---------- rNew
2312
2313 7. ------------- rOld
2314 ---------- rNew
2315
2316 8. ---------- rOld
2317 ------------- rNew
2318
2319 9. ---------- rOld
2320 ---------- rNew
2321*/
2322
2323SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const
2324{
2325 SwLineEntry::OverlapType eRet = OVERLAP3;
2326
2327 if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos )
2328 eRet = NO_OVERLAP;
2329
2330 // 1, 2, 3
2331 else if ( mnEndPos < rNew.mnEndPos )
2332 eRet = OVERLAP1;
2333
2334 // 4, 5, 6, 7
2335 else if (mnStartPos <= rNew.mnStartPos)
2336 eRet = OVERLAP2;
2337
2338 // 8, 9
2339 return eRet;
2340}
2341
2342void SwLineEntry::LimitVerticalEndPos(const SwFrame& rFrame, VerticalType eType)
2343{
2344 if (!rFrame.IsCellFrame())
2345 {
2346 return;
2347 }
2348
2349 const auto& rCellFrame = static_cast<const SwCellFrame&>(rFrame);
2350 std::vector<const SwCellFrame*> aCoveredCells = rCellFrame.GetCoveredCells();
2351 // Iterate in reverse order, so we can stop at the first cell that has a border. This can
2352 // determine what is the minimal end position that is safe to use as a limit.
2353 for (auto it = aCoveredCells.rbegin(); it != aCoveredCells.rend(); ++it)
2354 {
2355 const SwCellFrame* pCoveredCell = *it;
2356 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pCoveredCell );
2357 const SwBorderAttrs& rAttrs = *aAccess.Get();
2358 const SvxBoxItem& rBox = rAttrs.GetBox();
2359 if (eType == VerticalType::LEFT && rBox.GetLeft())
2360 {
2361 break;
2362 }
2363
2364 if (eType == VerticalType::RIGHT && rBox.GetRight())
2365 {
2366 break;
2367 }
2368
2369 mnLimitedEndPos = pCoveredCell->getFrameArea().Top();
2370 }
2371}
2372
2373namespace {
2374
2375struct lt_SwLineEntry
2376{
2377 bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const
2378 {
2379 return e1.mnStartPos < e2.mnStartPos;
2380 }
2381};
2382
2383}
2384
2385typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet;
2386typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap;
2387
2388namespace {
2389
2390class SwTabFramePainter
2391{
2392 SwLineEntryMap maVertLines;
2393 SwLineEntryMap maHoriLines;
2394 const SwTabFrame& mrTabFrame;
2395
2396 void Insert( SwLineEntry&, bool bHori );
2397 void Insert(const SwFrame& rFrame, const SvxBoxItem& rBoxItem, const SwRect &rPaintArea);
2398 void HandleFrame(const SwLayoutFrame& rFrame, const SwRect& rPaintArea);
2399 void FindStylesForLine( Point&,
2400 Point&,
2402 bool bHori,
2403 bool bOuter ) const;
2404
2405public:
2406 explicit SwTabFramePainter( const SwTabFrame& rTabFrame );
2407
2408 void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const;
2409};
2410
2411}
2412
2413SwTabFramePainter::SwTabFramePainter( const SwTabFrame& rTabFrame )
2414 : mrTabFrame( rTabFrame )
2415{
2416 SwRect aPaintArea = rTabFrame.GetUpper()->GetPaintArea();
2417 HandleFrame(rTabFrame, aPaintArea);
2418}
2419
2420void SwTabFramePainter::HandleFrame(const SwLayoutFrame& rLayoutFrame, const SwRect& rPaintArea)
2421{
2422 // Add border lines of cell frames. Skip covered cells. Skip cells
2423 // in special row span row, which do not have a negative row span:
2424 if ( rLayoutFrame.IsCellFrame() && !rLayoutFrame.IsCoveredCell() )
2425 {
2426 const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(&rLayoutFrame);
2427 const SwRowFrame* pRowFrame = static_cast<const SwRowFrame*>(pThisCell->GetUpper());
2428 const tools::Long nRowSpan = pThisCell->GetTabBox()->getRowSpan();
2429 if ( !pRowFrame->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 )
2430 {
2431 SwBorderAttrAccess aAccess( SwFrame::GetCache(), &rLayoutFrame );
2432 const SwBorderAttrs& rAttrs = *aAccess.Get();
2433 const SvxBoxItem& rBox = rAttrs.GetBox();
2434 Insert(rLayoutFrame, rBox, rPaintArea);
2435 }
2436 }
2437
2438 // Recurse into lower layout frames, but do not recurse into lower tabframes.
2439 const SwFrame* pLower = rLayoutFrame.Lower();
2440 while ( pLower )
2441 {
2442 if (pLower->IsLayoutFrame() && !pLower->IsTabFrame())
2443 {
2444 const SwLayoutFrame* pLowerLayFrame = static_cast<const SwLayoutFrame*>(pLower);
2445 HandleFrame(*pLowerLayFrame, rPaintArea);
2446 }
2447 pLower = pLower->GetNext();
2448 }
2449}
2450
2451void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) const
2452{
2453 // #i16816# tagged pdf support
2454 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, rDev );
2455
2456 SwLineEntryMap::const_iterator aIter = maHoriLines.begin();
2457 bool bHori = true;
2458
2459 // color for subsidiary lines:
2460 const Color& rCol( gProp.pSGlobalShell->GetViewOptions()->GetTableBoundariesColor() );
2461
2462 // high contrast mode:
2463 // overrides the color of non-subsidiary lines.
2464 const Color* pHCColor = nullptr;
2465 DrawModeFlags nOldDrawMode = rDev.GetDrawMode();
2466 if( gProp.pSGlobalShell->GetWin() &&
2468 {
2469 pHCColor = &gProp.pSGlobalShell->GetViewOptions()->GetFontColor();
2470 rDev.SetDrawMode( DrawModeFlags::Default );
2471 }
2472
2473 const SwFrame* pUpper = mrTabFrame.GetUpper();
2474 SwRect aUpper( pUpper->getFramePrintArea() );
2475 aUpper.Pos() += pUpper->getFrameArea().Pos();
2476 SwRect aUpperAligned( aUpper );
2477 ::SwAlignRect( aUpperAligned, gProp.pSGlobalShell, &rDev );
2478
2479 // prepare SdrFrameBorderDataVector
2481
2482 while ( true )
2483 {
2484 if ( bHori && aIter == maHoriLines.end() )
2485 {
2486 aIter = maVertLines.begin();
2487 bHori = false;
2488 }
2489
2490 if ( !bHori && aIter == maVertLines.end() )
2491 break;
2492
2493 const SwLineEntrySet& rEntrySet = (*aIter).second;
2494 for (const SwLineEntry& rEntry : rEntrySet)
2495 {
2496 const svx::frame::Style& rEntryStyle( rEntry.maAttribute );
2497
2498 Point aStart, aEnd;
2499 if ( bHori )
2500 {
2501 aStart.setX( rEntry.mnStartPos );
2502 aStart.setY( rEntry.mnKey );
2503 aEnd.setX( rEntry.mnEndPos );
2504 aEnd.setY( rEntry.mnKey );
2505 }
2506 else
2507 {
2508 aStart.setX( rEntry.mnKey );
2509 aStart.setY( rEntry.mnStartPos );
2510 aEnd.setX( rEntry.mnKey );
2511 aEnd.setY( rEntry.mnEndPos );
2512 }
2513
2514 svx::frame::Style aStyles[ 7 ];
2515 aStyles[ 0 ] = rEntryStyle;
2516 FindStylesForLine(aStart, aEnd, aStyles, bHori, rEntry.mbOuter);
2517
2518 if (!bHori && rEntry.mnLimitedEndPos)
2519 {
2520 aEnd.setY(rEntry.mnLimitedEndPos);
2521 }
2522
2523 SwRect aRepaintRect( aStart, aEnd );
2524
2525 // the repaint rectangle has to be moved a bit for the centered lines:
2526 SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth();
2527 if ( bHori )
2528 {
2529 aRepaintRect.Height( 2 * nRepaintRectSize );
2530 aRepaintRect.Pos().AdjustY( -nRepaintRectSize );
2531
2532 // To decide on visibility it is also necessary to expand the RepaintRect
2533 // to left/right according existing BorderLine overlap matchings, else there
2534 // will be repaint errors when scrolling in e.t TripleLine BorderLines.
2535 // aStyles[1] == aLFromT, aStyles[3] == aLFromB, aStyles[4] == aRFromT, aStyles[6] == aRFromB
2536 if(aStyles[1].IsUsed() || aStyles[3].IsUsed() || aStyles[4].IsUsed() || aStyles[6].IsUsed())
2537 {
2538 const double fLineWidthMaxLeft(std::max(aStyles[1].GetWidth(), aStyles[3].GetWidth()));
2539 const double fLineWidthMaxRight(std::max(aStyles[4].GetWidth(), aStyles[6].GetWidth()));
2540 aRepaintRect.Width(aRepaintRect.Width() + (fLineWidthMaxLeft + fLineWidthMaxRight));
2541 aRepaintRect.Pos().AdjustX( -fLineWidthMaxLeft );
2542 }
2543 }
2544 else
2545 {
2546 aRepaintRect.Width( 2 * nRepaintRectSize );
2547 aRepaintRect.Pos().AdjustX( -nRepaintRectSize );
2548
2549 // Accordingly to horizontal case, but for top/bottom
2550 // aStyles[3] == aTFromR, aStyles[1] == aTFromL, aStyles[6] == aBFromR, aStyles[4] == aBFromL
2551 if(aStyles[3].IsUsed() || aStyles[1].IsUsed() || aStyles[6].IsUsed() || aStyles[4].IsUsed())
2552 {
2553 const double fLineWidthMaxTop(std::max(aStyles[3].GetWidth(), aStyles[1].GetWidth()));
2554 const double fLineWidthMaxBottom(std::max(aStyles[6].GetWidth(), aStyles[4].GetWidth()));
2555 aRepaintRect.Height(aRepaintRect.Height() + (fLineWidthMaxTop + fLineWidthMaxBottom));
2556 aRepaintRect.Pos().AdjustY( -fLineWidthMaxTop );
2557 }
2558 }
2559
2560 if (!rRect.Overlaps(aRepaintRect))
2561 {
2562 continue;
2563 }
2564
2565 // subsidiary lines
2566 const Color* pTmpColor = nullptr;
2567 if (0 == aStyles[ 0 ].GetWidth())
2568 {
2569 if (isTableBoundariesEnabled() && gProp.pSGlobalShell->GetWin())
2570 aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
2571 else
2572 aStyles[0].SetType(SvxBorderLineStyle::NONE);
2573 }
2574 else
2575 pTmpColor = pHCColor;
2576
2577 // The (twip) positions will be adjusted to meet these requirements:
2578 // 1. The y coordinates are located in the middle of the pixel grid
2579 // 2. The x coordinated are located at the beginning of the pixel grid
2580 // This is done, because the horizontal lines are painted "at
2581 // beginning", whereas the vertical lines are painted "centered".
2582 // By making the line sizes a multiple of one pixel size, we can
2583 // assure that all lines having the same twip size have the same
2584 // pixel size, independent of their position on the screen.
2585 Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel(aStart) );
2586 Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel(aEnd) );
2587
2588 if (gProp.pSGlobalShell->GetWin())
2589 {
2590 // The table borders do not use SwAlignRect, but all the other frames do.
2591 // Therefore we tweak the outer borders a bit to achieve that the outer
2592 // borders match the subsidiary lines of the upper:
2593 if (aStart.X() == aUpper.Left())
2594 aPaintStart.setX( aUpperAligned.Left() );
2595 else if (aStart.X() == aUpper.Right_())
2596 aPaintStart.setX( aUpperAligned.Right_() );
2597 if (aStart.Y() == aUpper.Top())
2598 aPaintStart.setY( aUpperAligned.Top() );
2599 else if (aStart.Y() == aUpper.Bottom_())
2600 aPaintStart.setY( aUpperAligned.Bottom_() );
2601
2602 if (aEnd.X() == aUpper.Left())
2603 aPaintEnd.setX( aUpperAligned.Left() );
2604 else if (aEnd.X() == aUpper.Right_())
2605 aPaintEnd.setX( aUpperAligned.Right_() );
2606 if (aEnd.Y() == aUpper.Top())
2607 aPaintEnd.setY( aUpperAligned.Top() );
2608 else if (aEnd.Y() == aUpper.Bottom_())
2609 aPaintEnd.setY( aUpperAligned.Bottom_() );
2610 }
2611
2612 if(aStyles[0].IsUsed())
2613 {
2614 if (bHori)
2615 {
2616 const basegfx::B2DPoint aOrigin(aPaintStart.X(), aPaintStart.Y());
2617 const basegfx::B2DVector aX(basegfx::B2DPoint(aPaintEnd.X(), aPaintEnd.Y()) - aOrigin);
2618
2619 if(!aX.equalZero())
2620 {
2622 aData.emplace_back(
2623 aOrigin,
2624 aX,
2625 aStyles[0],
2626 pTmpColor);
2628
2629 rInstance.addSdrConnectStyleData(true, aStyles[1], -aY, true); // aLFromT
2630 rInstance.addSdrConnectStyleData(true, aStyles[2], -aX, true); // aLFromL
2631 rInstance.addSdrConnectStyleData(true, aStyles[3], aY, false); // aLFromB
2632
2633 rInstance.addSdrConnectStyleData(false, aStyles[4], -aY, true); // aRFromT
2634 rInstance.addSdrConnectStyleData(false, aStyles[5], aX, false); // aRFromR
2635 rInstance.addSdrConnectStyleData(false, aStyles[6], aY, false); // aRFromB
2636 }
2637 }
2638 else // vertical
2639 {
2640 const basegfx::B2DPoint aOrigin(aPaintStart.X(), aPaintStart.Y());
2641 const basegfx::B2DVector aX(basegfx::B2DPoint(aPaintEnd.X(), aPaintEnd.Y()) - aOrigin);
2642
2643 if(!aX.equalZero())
2644 {
2646 aData.emplace_back(
2647 aOrigin,
2648 aX,
2649 aStyles[0],
2650 pTmpColor);
2652
2653 rInstance.addSdrConnectStyleData(true, aStyles[3], -aY, false); // aTFromR
2654 rInstance.addSdrConnectStyleData(true, aStyles[2], -aX, true); // aTFromT
2655 rInstance.addSdrConnectStyleData(true, aStyles[1], aY, true); // aTFromL
2656
2657 rInstance.addSdrConnectStyleData(false, aStyles[6], -aY, false); // aBFromR
2658 rInstance.addSdrConnectStyleData(false, aStyles[5], aX, false); // aBFromB
2659 rInstance.addSdrConnectStyleData(false, aStyles[4], aY, true); // aBFromL
2660 }
2661 }
2662 }
2663 }
2664 ++aIter;
2665 }
2666
2667 // create instance of SdrFrameBorderPrimitive2D if
2668 // SdrFrameBorderDataVector is used
2669 if(!aData.empty())
2670 {
2672 aSequence.append(
2675 std::move(aData),
2676 true))); // force visualization to minimal one discrete unit (pixel)
2677 // paint
2678 mrTabFrame.ProcessPrimitives(aSequence);
2679 }
2680
2681 // restore output device:
2682 rDev.SetDrawMode( nOldDrawMode );
2683}
2684
2690void SwTabFramePainter::FindStylesForLine( Point& rStartPoint,
2691 Point& rEndPoint,
2692 svx::frame::Style* pStyles,
2693 bool bHori, bool bOuter ) const
2694{
2695 // For example, aLFromB means: this vertical line intersects my horizontal line at its left end,
2696 // from bottom.
2697 // pStyles[ 1 ] = bHori ? aLFromT : TFromL
2698 // pStyles[ 2 ] = bHori ? aLFromL : TFromT,
2699 // pStyles[ 3 ] = bHori ? aLFromB : TFromR,
2700 // pStyles[ 4 ] = bHori ? aRFromT : BFromL,
2701 // pStyles[ 5 ] = bHori ? aRFromR : BFromB,
2702 // pStyles[ 6 ] = bHori ? aRFromB : BFromR,
2703
2704 bool bWordTableCell = false;
2705 SwViewShell* pShell = mrTabFrame.getRootFrame()->GetCurrShell();
2706 if (pShell)
2707 {
2708 const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess();
2709 bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP);
2710 }
2711
2712 SwLineEntryMap::const_iterator aMapIter = maVertLines.find( rStartPoint.X() );
2713 OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
2714 const SwLineEntrySet& rVertSet = (*aMapIter).second;
2715
2716 for ( const SwLineEntry& rEntry : rVertSet )
2717 {
2718 if ( bHori )
2719 {
2720 if ( rStartPoint.Y() == rEntry.mnStartPos )
2721 pStyles[ 3 ] = rEntry.maAttribute;
2722 else if ( rStartPoint.Y() == rEntry.mnEndPos )
2723 pStyles[ 1 ] = rEntry.maAttribute;
2724
2725 if (bWordTableCell && rStartPoint.X() == rEntry.mnKey && !bOuter && rEntry.mbOuter)
2726 {
2727 rStartPoint.AdjustX(rEntry.maAttribute.GetWidth());
2728 }
2729 }
2730 else
2731 {
2732 if ( rStartPoint.Y() == rEntry.mnEndPos )
2733 pStyles[ 2 ] = rEntry.maAttribute;
2734 else if ( rEndPoint.Y() == rEntry.mnStartPos )
2735 pStyles[ 5 ] = rEntry.maAttribute;
2736 }
2737 }
2738
2739 aMapIter = maHoriLines.find( rStartPoint.Y() );
2740 OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
2741 const SwLineEntrySet& rHoriSet = (*aMapIter).second;
2742
2743 for ( const SwLineEntry& rEntry : rHoriSet )
2744 {
2745 if ( bHori )
2746 {
2747 if ( rStartPoint.X() == rEntry.mnEndPos )
2748 pStyles[ 2 ] = rEntry.maAttribute;
2749 else if ( rEndPoint.X() == rEntry.mnStartPos )
2750 pStyles[ 5 ] = rEntry.maAttribute;
2751 }
2752 else
2753 {
2754 if ( rStartPoint.X() == rEntry.mnEndPos )
2755 pStyles[ 1 ] = rEntry.maAttribute;
2756 else if ( rStartPoint.X() == rEntry.mnStartPos )
2757 pStyles[ 3 ] = rEntry.maAttribute;
2758
2759 if (bWordTableCell && rStartPoint.Y() == rEntry.mnKey && !bOuter && rEntry.mbOuter)
2760 {
2761 rStartPoint.AdjustY(rEntry.maAttribute.GetWidth());
2762 }
2763 }
2764 }
2765
2766 if ( bHori )
2767 {
2768 aMapIter = maVertLines.find( rEndPoint.X() );
2769 OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
2770 const SwLineEntrySet& rVertSet2 = (*aMapIter).second;
2771
2772 for ( const SwLineEntry& rEntry : rVertSet2 )
2773 {
2774 if ( rEndPoint.Y() == rEntry.mnStartPos )
2775 pStyles[ 6 ] = rEntry.maAttribute;
2776 else if ( rEndPoint.Y() == rEntry.mnEndPos )
2777 pStyles[ 4 ] = rEntry.maAttribute;
2778
2779 if (bWordTableCell && rEndPoint.X() == rEntry.mnKey && !bOuter && rEntry.mbOuter)
2780 {
2781 rEndPoint.AdjustX(-rEntry.maAttribute.GetWidth());
2782 }
2783 }
2784 }
2785 else
2786 {
2787 aMapIter = maHoriLines.find( rEndPoint.Y() );
2788 OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
2789 const SwLineEntrySet& rHoriSet2 = (*aMapIter).second;
2790
2791 for ( const SwLineEntry& rEntry : rHoriSet2 )
2792 {
2793 if ( rEndPoint.X() == rEntry.mnEndPos )
2794 pStyles[ 4 ] = rEntry.maAttribute;
2795 else if ( rEndPoint.X() == rEntry.mnStartPos )
2796 pStyles[ 6 ] = rEntry.maAttribute;
2797
2798 if (bWordTableCell && rEndPoint.Y() == rEntry.mnKey && !bOuter && rEntry.mbOuter)
2799 {
2800 rEndPoint.AdjustY(-rEntry.maAttribute.GetWidth());
2801 }
2802 }
2803 }
2804}
2805
2813 SwTabFrame const& rTabFrame, SwFrame const& rFrame, SvxBoxItem const& rBoxItem)
2814{
2815 SwRowFrame const*const pThisRowFrame =
2816 dynamic_cast<const SwRowFrame*>(rFrame.GetUpper());
2817 return (pThisRowFrame
2818 && (pThisRowFrame->GetUpper() == &rTabFrame)
2819 && ( rTabFrame.IsFollow()
2820 // tdf#150308 first table row isn't equal to the table row of the first
2821 // row frame of the first table frame: there are invisible deleted rows
2822 // in Hide Changes mode before the first visible table row
2823 || rTabFrame.GetTable()->GetTabLines().front() != pThisRowFrame->GetTabLine() )
2824 && !rTabFrame.GetTable()->GetRowsToRepeat()
2825 && ( !pThisRowFrame->GetPrev()
2826 || static_cast<const SwRowFrame*>(pThisRowFrame->GetPrev())
2827 ->IsRowSpanLine())
2828 && !rBoxItem.GetTop()
2829 && rBoxItem.GetBottom());
2830}
2831
2832void SwTabFramePainter::Insert(const SwFrame& rFrame, const SvxBoxItem& rBoxItem, const SwRect& rPaintArea)
2833{
2834 // build 4 line entries for the 4 borders:
2835 SwRect aBorderRect = rFrame.getFrameArea();
2836
2837 aBorderRect.Intersection(rPaintArea);
2838
2840 mrTabFrame, rFrame, rBoxItem));
2841 bool const bVert = mrTabFrame.IsVertical();
2842 bool const bR2L = mrTabFrame.IsRightToLeft();
2843
2844 bool bWordTableCell = false;
2845 SwViewShell* pShell = rFrame.getRootFrame()->GetCurrShell();
2846 if (pShell)
2847 {
2848 const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess();
2849 bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP);
2850 }
2851
2852 // no scaling needed, it's all in the primitives and the target device
2854 aL.SetWordTableCell(bWordTableCell);
2856 aR.SetWordTableCell(bWordTableCell);
2858 aT.SetWordTableCell(bWordTableCell);
2860 aB.SetWordTableCell(bWordTableCell);
2861
2862 // First cell in a row.
2863 bool bLeftIsOuter = rFrame.IsCellFrame() && rFrame.GetUpper()->GetLower() == &rFrame;
2864 // Last cell in a row.
2865 bool bRightIsOuter = rFrame.IsCellFrame() && rFrame.GetNext() == nullptr;
2866 // First row in a table.
2867 bool bTopIsOuter = rFrame.IsCellFrame() && rFrame.GetUpper()->GetUpper()->GetLower() == rFrame.GetUpper();
2868 // Last row in a table.
2869 bool bBottomIsOuter = rFrame.IsCellFrame() && rFrame.GetUpper()->GetNext() == nullptr;
2870
2871 aR.MirrorSelf();
2872 if (!bWordTableCell || !bBottomIsOuter)
2873 {
2874 // Outer horizontal lines are never mirrored in Word.
2875 aB.MirrorSelf();
2876 }
2877
2878 const SwTwips nLeft = aBorderRect.Left_();
2879 const SwTwips nRight = aBorderRect.Right_();
2880 const SwTwips nTop = aBorderRect.Top_();
2881 const SwTwips nBottom = aBorderRect.Bottom_();
2882
2883 aL.SetRefMode( svx::frame::RefMode::Centered );
2884 aR.SetRefMode( svx::frame::RefMode::Centered );
2885 aT.SetRefMode( !bVert ? svx::frame::RefMode::Begin : svx::frame::RefMode::End );
2886 aB.SetRefMode( !bVert ? svx::frame::RefMode::Begin : svx::frame::RefMode::End );
2887
2888 if (bWordTableCell && bLeftIsOuter)
2889 {
2890 // Outer vertical lines are always mirrored in Word.
2891 aL.MirrorSelf();
2892 }
2893
2894 SwLineEntry aLeft (nLeft, nTop, nBottom, bLeftIsOuter,
2895 bVert ? aB : (bR2L ? aR : aL));
2896 if (bWordTableCell && rBoxItem.GetLeft())
2897 {
2898 aLeft.LimitVerticalEndPos(rFrame, SwLineEntry::VerticalType::LEFT);
2899 }
2900
2901 SwLineEntry aRight (nRight, nTop, nBottom, bRightIsOuter,
2902 bVert ? (bBottomAsTop ? aB : aT) : (bR2L ? aL : aR));
2903 if (bWordTableCell && rBoxItem.GetRight())
2904 {
2905 aRight.LimitVerticalEndPos(rFrame, SwLineEntry::VerticalType::RIGHT);
2906 }
2907
2908 SwLineEntry aTop (nTop, nLeft, nRight, bTopIsOuter,
2909 bVert ? aL : (bBottomAsTop ? aB : aT));
2910
2911 SwLineEntry aBottom(nBottom, nLeft, nRight, bBottomIsOuter,
2912 bVert ? aR : aB);
2913
2914 Insert( aLeft, false );
2915 Insert( aRight, false );
2916 Insert( aTop, true );
2917 Insert( aBottom, true );
2918}
2919
2920void SwTabFramePainter::Insert( SwLineEntry& rNew, bool bHori )
2921{
2922 // get all lines from structure, that have key entry of pLE
2923 SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines;
2924 const SwTwips nKey = rNew.mnKey;
2925 SwLineEntryMap::iterator aMapIter = pLine2->find( nKey );
2926
2927 SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : nullptr;
2928 if ( !pLineSet )
2929 {
2930 SwLineEntrySet aNewSet;
2931 (*pLine2)[ nKey ] = aNewSet;
2932 pLineSet = &(*pLine2)[ nKey ];
2933 }
2934 SwLineEntrySet::iterator aIter = pLineSet->begin();
2935
2936 bool bWordTableCell = false;
2937 SwViewShell* pShell = mrTabFrame.getRootFrame()->GetCurrShell();
2938 if (pShell)
2939 {
2940 const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess();
2941 bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP);
2942 }
2943 while ( aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
2944 {
2945 const SwLineEntry& rOld = *aIter;
2946
2947 if (rOld.mnLimitedEndPos || (bWordTableCell && (rOld.mbOuter != rNew.mbOuter)))
2948 {
2949 // Don't merge with this line entry as it ends sooner than mnEndPos.
2950 ++aIter;
2951 continue;
2952 }
2953
2954 const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew );
2955
2956 const svx::frame::Style& rOldAttr = rOld.maAttribute;
2957 const svx::frame::Style& rNewAttr = rNew.maAttribute;
2958 const svx::frame::Style& rCmpAttr = std::max(rNewAttr, rOldAttr);
2959
2960 if ( SwLineEntry::OVERLAP1 == nOverlapType )
2961 {
2962 OSL_ENSURE( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" );
2963
2964 // new left segment
2965 const SwLineEntry aLeft(nKey, rOld.mnStartPos, rNew.mnStartPos, rOld.mbOuter, rOldAttr);
2966
2967 // new middle segment
2968 const SwLineEntry aMiddle(nKey, rNew.mnStartPos, rOld.mnEndPos, rOld.mbOuter, rCmpAttr);
2969
2970 // new right segment
2971 rNew.mnStartPos = rOld.mnEndPos;
2972
2973 // update current lines set
2974 pLineSet->erase( aIter );
2975 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2976 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2977
2978 aIter = pLineSet->begin();
2979
2980 continue; // start over
2981 }
2982 else if ( SwLineEntry::OVERLAP2 == nOverlapType )
2983 {
2984 // new left segment
2985 const SwLineEntry aLeft(nKey, rOld.mnStartPos, rNew.mnStartPos, rOld.mbOuter, rOldAttr);
2986
2987 // new middle segment
2988 const SwLineEntry aMiddle(nKey, rNew.mnStartPos, rNew.mnEndPos, rOld.mbOuter, rCmpAttr);
2989
2990 // new right segment
2991 const SwLineEntry aRight(nKey, rNew.mnEndPos, rOld.mnEndPos, rOld.mbOuter, rOldAttr);
2992
2993 // update current lines set
2994 pLineSet->erase( aIter );
2995 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
2996 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
2997 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
2998
2999 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
3000
3001 break; // we are finished
3002 }
3003 else if ( SwLineEntry::OVERLAP3 == nOverlapType )
3004 {
3005 // new left segment
3006 const SwLineEntry aLeft(nKey, rNew.mnStartPos, rOld.mnStartPos, rOld.mbOuter, rNewAttr);
3007
3008 // new middle segment
3009 const SwLineEntry aMiddle(nKey, rOld.mnStartPos, rNew.mnEndPos, rOld.mbOuter, rCmpAttr);
3010
3011 // new right segment
3012 const SwLineEntry aRight(nKey, rNew.mnEndPos, rOld.mnEndPos, rOld.mbOuter, rOldAttr);
3013
3014 // update current lines set
3015 pLineSet->erase( aIter );
3016 if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
3017 if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
3018 if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
3019
3020 rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
3021
3022 break; // we are finished
3023 }
3024
3025 ++aIter;
3026 }
3027
3028 if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest
3029 pLineSet->insert( rNew );
3030}
3031
3036namespace
3037{
3038 class SwViewObjectContactRedirector : public sdr::contact::ViewObjectContactRedirector
3039 {
3040 private:
3041 const SwViewShell& mrViewShell;
3042
3043 public:
3044 explicit SwViewObjectContactRedirector( const SwViewShell& rSh )
3045 : mrViewShell( rSh )
3046 {};
3047
3049 const sdr::contact::ViewObjectContact& rOriginal,
3050 const sdr::contact::DisplayInfo& rDisplayInfo,
3052 {
3053 bool bPaint( true );
3054
3055 SdrObject* pObj = rOriginal.GetViewContact().TryToGetSdrObject();
3056 if ( pObj )
3057 {
3058 bPaint = SwFlyFrame::IsPaint( pObj, &mrViewShell );
3059 }
3060
3061 if ( !bPaint )
3062 {
3063 return;
3064 }
3065
3067 rOriginal, rDisplayInfo, rVisitor );
3068 }
3069 };
3070
3071} // end of anonymous namespace
3072// <--
3073
3083void SwRootFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const pPrintData) const
3084{
3085 OSL_ENSURE( Lower() && Lower()->IsPageFrame(), "Lower of root is no page." );
3086
3087 PROTOCOL( this, PROT::FileInit, DbgAction::NONE, nullptr)
3088
3089 bool bResetRootPaint = false;
3090 SwViewShell *pSh = mpCurrShell;
3091
3092 if ( pSh->GetWin() )
3093 {
3094 if ( pSh->GetOut() == pSh->GetWin()->GetOutDev() && !pSh->GetWin()->IsVisible() )
3095 {
3096 return;
3097 }
3099 {
3100 SwPaintQueue::Add( pSh, rRect );
3101 return;
3102 }
3103 }
3104 else
3105 SwRootFrame::s_isInPaint = bResetRootPaint = true;
3106
3107 std::unique_ptr<SwSavePaintStatics> pStatics;
3108 if ( gProp.pSGlobalShell )
3109 pStatics.reset(new SwSavePaintStatics());
3110 gProp.pSGlobalShell = pSh;
3111
3112 if( !pSh->GetWin() )
3113 gProp.pSProgress = SfxProgress::GetActiveProgress( static_cast<SfxObjectShell*>(pSh->GetDoc()->GetDocShell()) );
3114
3115 ::SwCalcPixStatics( pSh->GetOut() );
3117
3118 // Copy rRect; for one, rRect could become dangling during the below action, and for another it
3119 // needs to be copied to aRect anyway as that is modified further down below:
3120 SwRect aRect( rRect );
3121
3122 //Trigger an action to clear things up if needed.
3123 //Using this trick we can ensure that all values are valid in all paints -
3124 //no problems, no special case(s).
3125 // #i92745#
3126 // Extend check on certain states of the 'current' <SwViewShell> instance to
3127 // all existing <SwViewShell> instances.
3128 bool bPerformLayoutAction( true );
3129 {
3130 for(SwViewShell& rTmpViewShell : pSh->GetRingContainer())
3131 {
3132 if ( rTmpViewShell.IsInEndAction() ||
3133 rTmpViewShell.IsPaintInProgress() ||
3134 ( rTmpViewShell.Imp()->IsAction() &&
3135 rTmpViewShell.Imp()->GetLayAction().IsActionInProgress() ) )
3136 {
3137 bPerformLayoutAction = false;
3138 }
3139
3140 if(!bPerformLayoutAction)
3141 break;
3142 }
3143 }
3144 if ( bPerformLayoutAction )
3145 {
3146 const_cast<SwRootFrame*>(this)->ResetTurbo();
3147 SwLayAction aAction( const_cast<SwRootFrame*>(this), pSh->Imp() );
3148 aAction.SetPaint( false );
3149 aAction.SetComplete( false );
3150 aAction.SetReschedule( gProp.pSProgress != nullptr );
3151 aAction.Action(&rRenderContext);
3153 if ( !pSh->ActionPend() )
3154 pSh->Imp()->DeletePaintRegion();
3155 }
3156
3157 aRect.Intersection( pSh->VisArea() );
3158
3159 const bool bExtraData = ::IsExtraData( GetFormat()->GetDoc() );
3160
3161 gProp.pSLines.reset(new SwLineRects); // Container for borders.
3162
3163 // #104289#. During painting, something (OLE) can
3164 // load the linguistic, which in turn can cause a reformat
3165 // of the document. Dangerous! We better set this flag to
3166 // avoid the reformat.
3167 const bool bOldAction = IsCallbackActionEnabled();
3168 const_cast<SwRootFrame*>(this)->SetCallbackActionEnabled( false );
3169
3170 const SwPageFrame *pPage = pSh->Imp()->GetFirstVisPage(&rRenderContext);
3171
3172 // #126222. The positions of headers and footers of the previous
3173 // pages have to be updated, else these headers and footers could
3174 // get visible at a wrong position.
3175 const SwPageFrame *pPageDeco = static_cast<const SwPageFrame*>(pPage->GetPrev());
3176 while (pPageDeco)
3177 {
3178 pPageDeco->PaintDecorators();
3179 OSL_ENSURE(!pPageDeco->GetPrev() || pPageDeco->GetPrev()->IsPageFrame(),
3180 "Neighbour of page is not a page.");
3181 pPageDeco = static_cast<const SwPageFrame*>(pPageDeco->GetPrev());
3182 }
3183
3184 const bool bBookMode = gProp.pSGlobalShell->GetViewOptions()->IsViewLayoutBookMode();
3185 if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrame*>(pPage->GetPrev())->IsEmptyPage() )
3186 pPage = static_cast<const SwPageFrame*>(pPage->GetPrev());
3187
3188 // #i68597#
3189 const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible());
3190
3191 // Hide all page break controls before showing them again
3192 SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( gProp.pSGlobalShell );
3193 if ( pWrtSh )
3194 {
3195 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3197 const SwPageFrame* pHiddenPage = pPage;
3198 while ( pHiddenPage->GetPrev() != nullptr )
3199 {
3200 pHiddenPage = static_cast< const SwPageFrame* >( pHiddenPage->GetPrev() );
3201 SwFrameControlPtr pControl = rMngr.GetControl( FrameControlType::PageBreak, pHiddenPage );
3202 if ( pControl )
3203 pControl->ShowAll( false );
3204 }
3205 }
3206
3207 // #i76669#
3208 SwViewObjectContactRedirector aSwRedirector( *pSh );
3209
3210 while ( pPage )
3211 {
3212 const bool bPaintRightShadow = pPage->IsRightShadowNeeded();
3213 const bool bPaintLeftShadow = pPage->IsLeftShadowNeeded();
3214 const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SidebarPosition::RIGHT;
3215
3216 if ( !pPage->IsEmptyPage() )
3217 {
3218 SwRect aPaintRect;
3219 SwPageFrame::GetBorderAndShadowBoundRect( pPage->getFrameArea(), pSh, &rRenderContext, aPaintRect,
3220 bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3221
3222 if ( aRect.Overlaps( aPaintRect ) )
3223 {
3224 if ( pSh->GetWin() )
3225 {
3226 gProp.pSSubsLines.reset(new SwSubsRects);
3227 gProp.pSSpecSubsLines.reset(new SwSubsRects);
3228 }
3229 gProp.pBLines.reset(new BorderLines);
3230
3231 aPaintRect.Intersection_( aRect );
3232
3233 if ( bExtraData &&
3234 pSh->GetWin() && pSh->IsInEndAction() )
3235 {
3236 // enlarge paint rectangle to complete page width, subtract
3237 // current paint area and invalidate the resulting region.
3238 SwRectFnSet aRectFnSet(pPage);
3239 SwRect aPageRectTemp( aPaintRect );
3240 aRectFnSet.SetLeftAndWidth( aPageRectTemp,
3241 aRectFnSet.GetLeft(pPage->getFrameArea()),
3242 aRectFnSet.GetWidth(pPage->getFrameArea()) );
3243 aPageRectTemp.Intersection_( pSh->VisArea() );
3244 vcl::Region aPageRectRegion( aPageRectTemp.SVRect() );
3245 aPageRectRegion.Exclude( aPaintRect.SVRect() );
3246 pSh->GetWin()->Invalidate( aPageRectRegion, InvalidateFlags::Children );
3247 }
3248
3249 // #i80793#
3250 // enlarge paint rectangle for objects overlapping the same pixel
3251 // in all cases and before the DrawingLayer overlay is initialized.
3252 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
3253
3254 // #i68597#
3255 // moved paint pre-process for DrawingLayer overlay here since the above
3256 // code dependent from bExtraData may expand the PaintRect
3257 {
3258 // #i75172# if called from SwViewShell::ImplEndAction it should no longer
3259 // really be used but handled by SwViewShell::ImplEndAction already
3260 const vcl::Region aDLRegion(aPaintRect.SVRect());
3261 pSh->DLPrePaint2(aDLRegion);
3262 }
3263
3264 if(OUTDEV_WINDOW == gProp.pSGlobalShell->GetOut()->GetOutDevType())
3265 {
3266 // changed method SwLayVout::Enter(..)
3267 // 2nd parameter is no longer <const> and will be set to the
3268 // rectangle the virtual output device is calculated from <aPaintRect>,
3269 // if the virtual output is used.
3270 s_pVout->Enter(pSh, aPaintRect, !s_isNoVirDev);
3271
3272 // Adjust paint rectangle to pixel size
3273 // Thus, all objects overlapping on pixel level with the unadjusted
3274 // paint rectangle will be considered in the paint.
3275 lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
3276 }
3277
3278 // maybe this can be put in the above scope. Since we are not sure, just leave it ATM
3279 s_pVout->SetOrgRect( aPaintRect );
3280
3281 // determine background color of page for <PaintLayer> method
3282 // calls, paint <hell> or <heaven>
3283 const Color aPageBackgrdColor(pPage->GetDrawBackgroundColor());
3284
3285 pPage->PaintBaBo( aPaintRect, pPage );
3286
3287 if ( pSh->Imp()->HasDrawView() )
3288 {
3289 gProp.pSLines->LockLines( true );
3291 pSh->Imp()->PaintLayer( rIDDMA.GetHellId(),
3292 pPrintData,
3293 *pPage, pPage->getFrameArea(),
3294 &aPageBackgrdColor,
3295 pPage->IsRightToLeft(),
3296 &aSwRedirector );
3297 gProp.pSLines->PaintLines( pSh->GetOut(), gProp );
3298 gProp.pSLines->LockLines( false );
3299 }
3300
3302 pPage->PaintBaBo( aPaintRect, pPage, /*bOnlyTextBackground=*/true );
3303
3304 if( pSh->GetWin() )
3305 {
3306 // collect sub-lines
3307 pPage->RefreshSubsidiary( aPaintRect );
3308 // paint special sub-lines
3309 gProp.pSSpecSubsLines->PaintSubsidiary( pSh->GetOut(), nullptr, gProp );
3310 }
3311
3312 pPage->PaintSwFrame( rRenderContext, aPaintRect );
3313
3314 // no paint of page border and shadow, if writer is in place mode.
3315 if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() &&
3316 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3317 {
3318 SwPageFrame::PaintBorderAndShadow( pPage->getFrameArea(), pSh, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3319 SwPageFrame::PaintNotesSidebar( pPage->getFrameArea(), pSh, pPage->GetPhyPageNum(), bRightSidebar);
3320 }
3321
3322 gProp.pSLines->PaintLines( pSh->GetOut(), gProp );
3323 if ( pSh->GetWin() )
3324 {
3325 gProp.pSSubsLines->PaintSubsidiary( pSh->GetOut(), gProp.pSLines.get(), gProp );
3326 gProp.pSSubsLines.reset();
3327 gProp.pSSpecSubsLines.reset();
3328 }
3329 // fdo#42750: delay painting these until after subsidiary lines
3330 // fdo#45562: delay painting these until after hell layer
3331 // fdo#47717: but do it before heaven layer
3332 ProcessPrimitives(gProp.pBLines->GetBorderLines_Clear());
3333
3334 if ( pSh->Imp()->HasDrawView() )
3335 {
3337 pPrintData,
3338 *pPage, pPage->getFrameArea(),
3339 &aPageBackgrdColor,
3340 pPage->IsRightToLeft(),
3341 &aSwRedirector );
3342 }
3343
3344 if ( bExtraData )
3345 pPage->RefreshExtraData( aPaintRect );
3346
3347 gProp.pBLines.reset();
3348 s_pVout->Leave();
3349
3350 // #i68597#
3351 // needed to move grid painting inside Begin/EndDrawLayer bounds and to change
3352 // output rect for it accordingly
3353 if(bGridPainting)
3354 {
3355 SdrPaintView* pPaintView = pSh->Imp()->GetDrawView();
3356 SdrPageView* pPageView = pPaintView->GetSdrPageView();
3357 pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), pSh->GetViewOptions()->GetTextGridColor() );
3358 }
3359
3360 // #i68597#
3361 // moved paint post-process for DrawingLayer overlay here, see above
3362 {
3363 pSh->DLPostPaint2(true);
3364 }
3365 }
3366
3367 pPage->PaintDecorators( );
3368 pPage->PaintBreak();
3369 }
3370 else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
3371 {
3372 // paint empty page
3373 SwRect aPaintRect;
3374 SwRect aEmptyPageRect( pPage->getFrameArea() );
3375
3376 // code from vprint.cxx
3377 const SwPageFrame& rFormatPage = pPage->GetFormatPage();
3378 aEmptyPageRect.SSize( rFormatPage.getFrameArea().SSize() );
3379
3380 SwPageFrame::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, &rRenderContext, aPaintRect,
3381 bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3382 aPaintRect.Intersection_( aRect );
3383
3384 if ( aRect.Overlaps( aEmptyPageRect ) )
3385 {
3386 // #i75172# if called from SwViewShell::ImplEndAction it should no longer
3387 // really be used but handled by SwViewShell::ImplEndAction already
3388 {
3389 const vcl::Region aDLRegion(aPaintRect.SVRect());
3390 pSh->DLPrePaint2(aDLRegion);
3391 }
3392
3393 if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor )
3395 // No line color
3396 pSh->GetOut()->SetLineColor();
3397 // Use aligned page rectangle
3398 {
3399 SwRect aTmpPageRect( aEmptyPageRect );
3400 ::SwAlignRect( aTmpPageRect, pSh, &rRenderContext );
3401 aEmptyPageRect = aTmpPageRect;
3402 }
3403
3404 pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() );
3405
3406 // paint empty page text
3407 const vcl::Font& rEmptyPageFont = SwPageFrame::GetEmptyPageFont();
3408 const vcl::Font aOldFont( pSh->GetOut()->GetFont() );
3409
3410 pSh->GetOut()->SetFont( rEmptyPageFont );
3411 pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SwResId( STR_EMPTYPAGE ),
3412 DrawTextFlags::VCenter |
3413 DrawTextFlags::Center |
3414 DrawTextFlags::Clip );
3415
3416 pSh->GetOut()->SetFont( aOldFont );
3417 // paint shadow and border for empty page
3418 SwPageFrame::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
3419 SwPageFrame::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar);
3420
3421 {
3422 pSh->DLPostPaint2(true);
3423 }
3424 }
3425 }
3426
3427 OSL_ENSURE( !pPage->GetNext() || pPage->GetNext()->IsPageFrame(),
3428 "Neighbour of page is not a page." );
3429 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
3430 }
3431
3432 gProp.pSLines.reset();
3433
3434 if ( bResetRootPaint )
3436 if ( pStatics )
3437 pStatics.reset();
3438 else
3439 {
3440 gProp.pSProgress = nullptr;
3441 gProp.pSGlobalShell = nullptr;
3442 }
3443
3444 const_cast<SwRootFrame*>(this)->SetCallbackActionEnabled( bOldAction );
3445}
3446
3448{
3449 vcl::RenderContext* pRenderContext = pCont->getRootFrame()->GetCurrShell()->GetOut();
3450
3451 //It's possible that the Cont will get destroyed.
3452 SwContentFrame *pCnt = pCont->ContainsContent();
3453 while ( pCnt && pCnt->IsInFootnote() )
3454 {
3455 pCnt->Calc(pRenderContext);
3456 pCnt = pCnt->GetNextContentFrame();
3457 }
3458}
3459
3460namespace {
3461
3462class SwShortCut
3463{
3464 SwRectDist m_fnCheck;
3465 tools::Long m_nLimit;
3466
3467public:
3468 SwShortCut( const SwFrame& rFrame, const SwRect& rRect );
3469 bool Stop(const SwRect& rRect) const { return (rRect.*m_fnCheck)(m_nLimit) > 0; }
3470};
3471
3472}
3473
3474SwShortCut::SwShortCut( const SwFrame& rFrame, const SwRect& rRect )
3475{
3476 bool bVert = rFrame.IsVertical();
3477 bool bR2L = rFrame.IsRightToLeft();
3478 if( rFrame.IsNeighbourFrame() && bVert == bR2L )
3479 {
3480 if( bVert )
3481 {
3482 m_fnCheck = &SwRect::GetBottomDistance;
3483 m_nLimit = rRect.Top();
3484 }
3485 else
3486 {
3487 m_fnCheck = &SwRect::GetLeftDistance;
3488 m_nLimit = rRect.Left() + rRect.Width();
3489 }
3490 }
3491 else if( bVert == rFrame.IsNeighbourFrame() )
3492 {
3493 m_fnCheck = &SwRect::GetTopDistance;
3494 m_nLimit = rRect.Top() + rRect.Height();
3495 }
3496 else
3497 {
3498 if ( rFrame.IsVertLR() )
3499 {
3500 m_fnCheck = &SwRect::GetLeftDistance;
3501 m_nLimit = rRect.Right();
3502 }
3503 else
3504 {
3505 m_fnCheck = &SwRect::GetRightDistance;
3506 m_nLimit = rRect.Left();
3507 }
3508 }
3509}
3510
3511void SwLayoutFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
3512{
3513 // #i16816# tagged pdf support
3514 Frame_Info aFrameInfo(*this, false);
3515 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, &aFrameInfo, nullptr, rRenderContext );
3516 ::std::optional<SwTaggedPDFHelper> oTaggedLink;
3517 if (IsFlyFrame())
3518 {
3519 // tdf#154939 Link nested inside Figure
3520 auto const pItem(GetFormat()->GetAttrSet().GetItemIfSet(RES_URL));
3521 if (pItem && !pItem->GetURL().isEmpty())
3522 {
3523 Frame_Info linkInfo(*this, true);
3524 oTaggedLink.emplace(nullptr, &linkInfo, nullptr, rRenderContext);
3525 }
3526 }
3527
3528 const SwFrame *pFrame = Lower();
3529 if ( !pFrame )
3530 return;
3531
3532 SwFrameDeleteGuard g(const_cast<SwLayoutFrame*>(this)); // lock because Calc() and recursion
3533 SwShortCut aShortCut( *pFrame, rRect );
3534 bool bCnt = pFrame->IsContentFrame();
3535 if ( bCnt )
3536 pFrame->Calc(&rRenderContext);
3537
3538 if ( pFrame->IsFootnoteContFrame() )
3539 {
3540 ::lcl_EmergencyFormatFootnoteCont( const_cast<SwFootnoteContFrame*>(static_cast<const SwFootnoteContFrame*>(pFrame)) );
3541 pFrame = Lower();
3542 }
3543
3544 const SwPageFrame *pPage = nullptr;
3545 bool bWin = gProp.pSGlobalShell->GetWin() != nullptr;
3547 // Tiled rendering is similar to printing in this case: painting transparently multiple
3548 // times will result in darker colors: avoid that.
3549 bWin = false;
3550
3551 while ( IsAnLower( pFrame ) )
3552 {
3553 SwRect aPaintRect( pFrame->GetPaintArea() );
3554 if( aShortCut.Stop( aPaintRect ) )
3555 break;
3556 if ( bCnt && gProp.pSProgress )
3558
3559 //We need to retouch if a frame explicitly requests it.
3560 //First do the retouch, because this could flatten the borders.
3561 if ( pFrame->IsRetouche() )
3562 {
3563 if ( pFrame->IsRetoucheFrame() && bWin && !pFrame->GetNext() )
3564 {
3565 if ( !pPage )
3566 pPage = FindPageFrame();
3567 pFrame->Retouch( pPage, rRect );
3568 }
3569 pFrame->ResetRetouche();
3570 }
3571
3572 if ( rRect.Overlaps( aPaintRect ) )
3573 {
3574 if ( bCnt && pFrame->IsCompletePaint() &&
3575 !rRect.Contains( aPaintRect ) && Application::AnyInput( VclInputFlags::KEYBOARD ) )
3576 {
3577 //fix(8104): It may happen, that the processing wasn't complete
3578 //but some parts of the paragraph were still repainted.
3579 //This could lead to the situation, that other parts of the
3580 //paragraph won't be repainted at all. The only solution seems
3581 //to be an invalidation of the window.
3582 //To not make it too severe the rectangle is limited by
3583 //painting the desired part and only invalidating the
3584 //remaining paragraph parts.
3585 if ( aPaintRect.Left() == rRect.Left() &&
3586 aPaintRect.Right() == rRect.Right() )
3587 {
3588 aPaintRect.Bottom( rRect.Top() - 1 );
3589 if ( aPaintRect.Height() > 0 )
3590 gProp.pSGlobalShell->InvalidateWindows(aPaintRect);
3591 aPaintRect.Top( rRect.Bottom() + 1 );
3592 aPaintRect.Bottom( pFrame->getFrameArea().Bottom() );
3593 if ( aPaintRect.Height() > 0 )
3594 gProp.pSGlobalShell->InvalidateWindows(aPaintRect);
3595 aPaintRect.Top( pFrame->getFrameArea().Top() );
3596 aPaintRect.Bottom( pFrame->getFrameArea().Bottom() );
3597 }
3598 else
3599 {
3600 gProp.pSGlobalShell->InvalidateWindows( aPaintRect );
3601 pFrame = pFrame->GetNext();
3602 if ( pFrame )
3603 {
3604 bCnt = pFrame->IsContentFrame();
3605 if ( bCnt )
3606 pFrame->Calc(&rRenderContext);
3607 }
3608 continue;
3609 }
3610 }
3611 pFrame->ResetCompletePaint();
3612 aPaintRect.Intersection_( rRect );
3613
3614 pFrame->PaintSwFrame( rRenderContext, aPaintRect );
3615
3616 if ( Lower() && Lower()->IsColumnFrame() )
3617 {
3618 //Paint the column separator line if needed. The page is
3619 //responsible for the page frame - not the upper.
3620 const SwFrameFormat *pFormat = GetUpper() && GetUpper()->IsPageFrame()
3621 ? GetUpper()->GetFormat()
3622 : GetFormat();
3623 const SwFormatCol &rCol = pFormat->GetCol();
3624 if ( rCol.GetLineAdj() != COLADJ_NONE )
3625 {
3626 if ( !pPage )
3627 pPage = pFrame->FindPageFrame();
3628
3629 PaintColLines( aPaintRect, rCol, pPage );
3630 }
3631 }
3632 }
3633 if ( !bCnt && pFrame->GetNext() && pFrame->GetNext()->IsFootnoteContFrame() )
3634 ::lcl_EmergencyFormatFootnoteCont( const_cast<SwFootnoteContFrame*>(static_cast<const SwFootnoteContFrame*>(pFrame->GetNext())) );
3635
3636 pFrame = pFrame->GetNext();
3637
3638 if ( pFrame )
3639 {
3640 bCnt = pFrame->IsContentFrame();
3641 if ( bCnt )
3642 pFrame->Calc(&rRenderContext);
3643 }
3644 }
3645}
3646
3648 const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd,
3649 basegfx::BColor aColor )
3650{
3652
3653 std::vector< double > aStrokePattern;
3654 basegfx::B2DPolygon aLinePolygon;
3655 aLinePolygon.append(rStart);
3656 aLinePolygon.append(rEnd);
3657
3659 if ( rSettings.GetHighContrastMode( ) )
3660 {
3661 // Only a solid line in high contrast mode
3662 aColor = rSettings.GetDialogTextColor().getBColor();
3663 }
3664 else
3665 {
3666 // Get a color for the contrast
3667 basegfx::BColor aHslLine = basegfx::utils::rgb2hsl( aColor );
3668 double nLuminance = aHslLine.getZ() * 2.5;
3669 if ( nLuminance == 0 )
3670 nLuminance = 0.5;
3671 else if ( nLuminance >= 1.0 )
3672 nLuminance = aHslLine.getZ() * 0.4;
3673 aHslLine.setZ( nLuminance );
3674 const basegfx::BColor aOtherColor = basegfx::utils::hsl2rgb( aHslLine );
3675
3676 // Compute the plain line
3677 aSeq[0] =
3679 aLinePolygon, aOtherColor );
3680
3681 // Dashed line in twips
3682 aStrokePattern.push_back( 40 );
3683 aStrokePattern.push_back( 40 );
3684
3685 aSeq.resize( 2 );
3686 }
3687
3688 // Compute the dashed line primitive
3689 aSeq[ aSeq.size( ) - 1 ] =
3691 basegfx::B2DPolyPolygon( aLinePolygon ),
3693 drawinglayer::attribute::StrokeAttribute( std::move(aStrokePattern) ) );
3694
3695
3696 return aSeq;
3697}
3698
3700{
3701 if ( gProp.pSGlobalShell->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
3702 gProp.pSGlobalShell->GetViewOptions()->IsPDFExport() ||
3703 gProp.pSGlobalShell->GetViewOptions()->IsReadonly() ||
3704 gProp.pSGlobalShell->IsPreview() )
3705 return;
3706
3707 const SwFrame* pBodyFrame = Lower();
3708 while ( pBodyFrame && !pBodyFrame->IsBodyFrame() )
3709 pBodyFrame = pBodyFrame->GetNext();
3710
3711 if ( pBodyFrame )
3712 {
3713 const SwLayoutFrame* pLayBody = static_cast< const SwLayoutFrame* >( pBodyFrame );
3714 const SwFlowFrame *pFlowFrame = pLayBody->ContainsContent();
3715
3716 // Test if the first node is a table
3717 const SwFrame* pFirstFrame = pLayBody->Lower();
3718 if ( pFirstFrame && pFirstFrame->IsTabFrame() )
3719 pFlowFrame = static_cast< const SwTabFrame* >( pFirstFrame );
3720
3721 SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( gProp.pSGlobalShell );
3722 if ( pWrtSh )
3723 {
3724 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3726
3727 if ( pFlowFrame && pFlowFrame->IsPageBreak( true ) )
3728 rMngr.SetPageBreakControl( this );
3729 else
3731 }
3732 }
3734}
3735
3737{
3738 if ( gProp.pSGlobalShell->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
3739 gProp.pSGlobalShell->GetViewOptions()->IsPDFExport() ||
3740 gProp.pSGlobalShell->GetViewOptions()->IsReadonly() ||
3741 gProp.pSGlobalShell->IsPreview() )
3742 return;
3743
3744 const SwFrame* pBodyFrame = Lower();
3745 while ( pBodyFrame && !pBodyFrame->IsBodyFrame() )
3746 pBodyFrame = pBodyFrame->GetNext();
3747
3748 if ( !pBodyFrame )
3749 return;
3750
3751 const SwContentFrame *pCnt = static_cast< const SwLayoutFrame* >( pBodyFrame )->ContainsContent();
3752 if ( !(pCnt && pCnt->IsColBreak( true )) )
3753 return;
3754
3755 // Paint the break only if:
3756 // * Not in header footer edition, to avoid conflicts with the
3757 // header/footer marker
3758 // * Non-printing characters are shown, as this is more consistent
3759 // with other formatting marks
3760 if ( !(!gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Header ) &&
3761 !gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Footer ) &&
3762 gProp.pSGlobalShell->GetViewOptions()->IsLineBreak()) )
3763 return;
3764
3765 SwRect aRect( pCnt->getFramePrintArea() );
3766 aRect.Pos() += pCnt->getFrameArea().Pos();
3767
3768 // Draw the line
3769 basegfx::B2DPoint aStart( double( aRect.Left() ), aRect.Top() );
3770 basegfx::B2DPoint aEnd( double( aRect.Right() ), aRect.Top() );
3771 double nWidth = aRect.Width();
3772 if ( IsVertical( ) )
3773 {
3774 aStart = basegfx::B2DPoint( double( aRect.Right() ), double( aRect.Top() ) );
3775 aEnd = basegfx::B2DPoint( double( aRect.Right() ), double( aRect.Bottom() ) );
3776 nWidth = aRect.Height();
3777 }
3778
3779 basegfx::BColor aLineColor = gProp.pSGlobalShell->GetViewOptions()->GetPageBreakColor().getBColor();
3780
3782 lcl_CreateDashedIndicatorPrimitive( aStart, aEnd, aLineColor );
3783
3784 // Add the text above
3785 OUString aBreakText = SwResId(STR_COLUMN_BREAK);
3786
3787 basegfx::B2DVector aFontSize;
3788 OutputDevice* pOut = gProp.pSGlobalShell->GetOut();
3789 vcl::Font aFont = pOut->GetSettings().GetStyleSettings().GetToolFont();
3790 aFont.SetFontHeight( 8 * 20 );
3791 pOut->SetFont( aFont );
3793 aFontSize, aFont, IsRightToLeft(), false );
3794
3795 tools::Rectangle aTextRect;
3796 pOut->GetTextBoundRect( aTextRect, aBreakText );
3797 tools::Long nTextOff = ( nWidth - aTextRect.GetWidth() ) / 2;
3798
3800 aFontSize.getX(), aFontSize.getY(),
3801 aRect.Left() + nTextOff, aRect.Top() ) );
3802 if ( IsVertical() )
3803 {
3805 aFontSize.getX(), aFontSize.getY(), 0.0, M_PI_2,
3806 aRect.Right(), aRect.Top() + nTextOff );
3807 }
3808
3809 aSeq.push_back(
3811 aTextMatrix,
3812 aBreakText, 0, aBreakText.getLength(),
3813 std::vector< double >(),
3814 {},
3815 std::move(aFontAttr),
3816 lang::Locale(),
3817 aLineColor ) );
3818
3820}
3821
3823{
3824 const SwFrame* pFrame = Lower();
3825 while ( pFrame )
3826 {
3827 if ( pFrame->IsLayoutFrame() )
3828 static_cast< const SwLayoutFrame*>( pFrame )->PaintBreak( );
3829 pFrame = pFrame->GetNext();
3830 }
3831}
3832
3834{
3835 SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( gProp.pSGlobalShell );
3836 if ( !pWrtSh )
3837 return;
3838
3839 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
3840
3841 const SwLayoutFrame* pBody = FindBodyCont();
3842 if ( !pBody )
3843 return;
3844
3845 SwRect aBodyRect( pBody->getFrameArea() );
3846
3847 if ( !(gProp.pSGlobalShell->GetOut()->GetOutDevType() != OUTDEV_PRINTER &&
3848 !gProp.pSGlobalShell->GetViewOptions()->IsPDFExport() &&
3849 !gProp.pSGlobalShell->IsPreview() &&
3850 !gProp.pSGlobalShell->GetViewOptions()->IsReadonly() &&
3851 !gProp.pSGlobalShell->GetViewOptions()->getBrowseMode() &&
3852 ( gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Header ) ||
3853 gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Footer ) )) )
3854 return;
3855
3856 bool bRtl = AllSettings::GetLayoutRTL();
3857 const SwRect& rVisArea = gProp.pSGlobalShell->VisArea();
3858 tools::Long nXOff = std::min( aBodyRect.Right(), rVisArea.Right() );
3859 if ( bRtl )
3860 nXOff = std::max( aBodyRect.Left(), rVisArea.Left() );
3861
3862 // Header
3863 if ( gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Header ) )
3864 {
3865 const SwFrame* pHeaderFrame = Lower();
3866 if ( !pHeaderFrame->IsHeaderFrame() )
3867 pHeaderFrame = nullptr;
3868
3869 tools::Long nHeaderYOff = aBodyRect.Top();
3870 Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nHeaderYOff ) );
3872 }
3873
3874 // Footer
3875 if ( !gProp.pSGlobalShell->IsShowHeaderFooterSeparator( FrameControlType::Footer ) )
3876 return;
3877
3878 const SwFrame* pFootnoteContFrame = Lower();
3879 while ( pFootnoteContFrame )
3880 {
3881 if ( pFootnoteContFrame->IsFootnoteContFrame() )
3882 aBodyRect.AddBottom( pFootnoteContFrame->getFrameArea().Bottom() - aBodyRect.Bottom() );
3883 pFootnoteContFrame = pFootnoteContFrame->GetNext();
3884 }
3885
3886 tools::Long nFooterYOff = aBodyRect.Bottom();
3887 Point nOutputOff = rEditWin.LogicToPixel( Point( nXOff, nFooterYOff ) );
3889}
3890
3905{
3906 bool bBackgroundTransparent = GetFormat()->IsBackgroundTransparent();
3907 if ( !bBackgroundTransparent &&
3908 GetFormat()->IsBackgroundBrushInherited() )
3909 {
3910 const SvxBrushItem* pBackgroundBrush = nullptr;
3911 std::optional<Color> xSectionTOXColor;
3912 SwRect aDummyRect;
3914
3915 if ( GetBackgroundBrush( aFillAttributes, pBackgroundBrush, xSectionTOXColor, aDummyRect, false, /*bConsiderTextBox=*/false) )
3916 {
3917 if ( xSectionTOXColor &&
3918 (xSectionTOXColor->IsTransparent()) &&
3919 (xSectionTOXColor != COL_TRANSPARENT) )
3920 {
3921 bBackgroundTransparent = true;
3922 }
3923 else if(aFillAttributes && aFillAttributes->isUsed())
3924 {
3925 bBackgroundTransparent = aFillAttributes->isTransparent();
3926 }
3927 else if ( pBackgroundBrush )
3928 {
3929 if ( (pBackgroundBrush->GetColor().IsTransparent()) &&
3930 (pBackgroundBrush->GetColor() != COL_TRANSPARENT) )
3931 {
3932 bBackgroundTransparent = true;
3933 }
3934 else
3935 {
3936 const GraphicObject *pTmpGrf =
3937 pBackgroundBrush->GetGraphicObject();
3938 if ( pTmpGrf &&
3939 (pTmpGrf->GetAttr().IsTransparent())
3940 )
3941 {
3942 bBackgroundTransparent = true;
3943 }
3944 }
3945 }
3946 }
3947 }
3948
3949 return bBackgroundTransparent;
3950};
3951
3953{
3954 SdrObjUserCall *pUserCall = GetUserCall(pObj);
3955
3956 if ( nullptr == pUserCall )
3957 return true;
3958
3959 //Attribute dependent, don't paint for printer or Preview
3960 bool bPaint = gProp.pSFlyOnlyDraw ||
3961 static_cast<SwContact*>(pUserCall)->GetFormat()->GetPrint().GetValue();
3962 if ( !bPaint )
3963 bPaint = pSh->GetWin() && !pSh->IsPreview();
3964
3965 if ( bPaint )
3966 {
3967 //The paint may be prevented by the superior Flys.
3968 SwFrame *pAnch = nullptr;
3969 if ( dynamic_cast< const SwFlyDrawObj *>( pObj ) != nullptr ) // i#117962#
3970 {
3971 bPaint = false;
3972 }
3973 if ( auto pFlyDraw = dynamic_cast<SwVirtFlyDrawObj *>( pObj ) )
3974 {
3975 SwFlyFrame *pFly = pFlyDraw->GetFlyFrame();
3976 if ( gProp.pSFlyOnlyDraw && gProp.pSFlyOnlyDraw == pFly )
3977 return true;
3978
3979 //Try to avoid displaying the intermediate stage, Flys which don't
3980 //overlap with the page on which they are anchored won't be
3981 //painted.
3982 //HACK: exception: printing of frames in tables, those can overlap
3983 //a page once in a while when dealing with oversized tables (HTML).
3984 SwPageFrame *pPage = pFly->FindPageFrame();
3985 if ( pPage && pPage->getFrameArea().Overlaps( pFly->getFrameArea() ) )
3986 {
3987 pAnch = pFly->AnchorFrame();
3988 }
3989
3990 }
3991 else
3992 {
3993 // Consider 'virtual' drawing objects
3994 SwDrawContact* pDrawContact = dynamic_cast<SwDrawContact*>(pUserCall);
3995 pAnch = pDrawContact ? pDrawContact->GetAnchorFrame(pObj) : nullptr;
3996 if ( pAnch )
3997 {
3998 if ( !pAnch->isFrameAreaPositionValid() )
3999 pAnch = nullptr;
4000 else if ( pSh->GetOut() == pSh->getIDocumentDeviceAccess().getPrinter( false ))
4001 {
4002 //HACK: we have to omit some of the objects for printing,
4003 //otherwise they would be printed twice.
4004 //The objects should get printed if the TableHack is active
4005 //right now. Afterwards they must not be printed if the
4006 //page over which they float position wise gets printed.
4007 const SwPageFrame *pPage = pAnch->FindPageFrame();
4008 if ( !pPage->getFrameArea().Overlaps( SwRect(pObj->GetCurrentBoundRect()) ) )
4009 pAnch = nullptr;
4010 }
4011 }
4012 else
4013 {
4014 if ( dynamic_cast< const SdrObjGroup *>( pObj ) == nullptr )
4015 {
4016 OSL_FAIL( "<SwFlyFrame::IsPaint(..)> - paint of drawing object without anchor frame!?" );
4017 }
4018 }
4019 }
4020 if ( pAnch )
4021 {
4022 if ( pAnch->IsInFly() )
4023 bPaint = SwFlyFrame::IsPaint( pAnch->FindFlyFrame()->GetVirtDrawObj(),
4024 pSh );
4025 else if ( gProp.pSFlyOnlyDraw )
4026 bPaint = false;
4027 }
4028 else
4029 bPaint = false;
4030 }
4031 return bPaint;
4032}
4033
4034void SwCellFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
4035{
4036 if ( GetLayoutRowSpan() >= 1 )
4037 SwLayoutFrame::PaintSwFrame( rRenderContext, rRect );
4038}
4039
4040namespace {
4041
4042struct BorderLinesGuard
4043{
4044 explicit BorderLinesGuard() : m_pBorderLines(std::move(gProp.pBLines))
4045 {
4046 gProp.pBLines.reset(new BorderLines);
4047 }
4048 ~BorderLinesGuard()
4049 {
4050 gProp.pBLines = std::move(m_pBorderLines);
4051 }
4052private:
4053 std::unique_ptr<BorderLines> m_pBorderLines;
4054};
4055
4056}
4057
4058// set strikethrough for deleted objects anchored to character
4060{
4061 if ( SwSortedObjs *pObjs = GetDrawObjs() )
4062 {
4063 for (SwAnchoredObject* pAnchoredObj : *pObjs)
4064 {
4065 if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
4066 {
4067 pFly->SetDeleted(bDeleted);
4068 }
4069 }
4070 }
4071}
4072
4073void SwFlyFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
4074{
4075 //optimize thumbnail generation and store procedure to improve odt saving performance, #i120030#
4076 SwViewShell *pShell = getRootFrame()->GetCurrShell();
4077 if (pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocShell())
4078 {
4079 bool bInGenerateThumbnail = pShell->GetDoc()->GetDocShell()->IsInGenerateAndStoreThumbnail();
4080 if (bInGenerateThumbnail)
4081 {
4082 const SwRect& aVisRect = pShell->VisArea();
4083 if (!aVisRect.Overlaps(getFrameArea()))
4084 return;
4085 }
4086 }
4087
4088 //because of the overlapping of frames and drawing objects the flys have to
4089 //paint their borders (and those of the internal ones) directly.
4090 //e.g. #33066#
4091 gProp.pSLines->LockLines(true);
4092 BorderLinesGuard blg; // this should not paint borders added from PaintBaBo
4093
4094 SwRect aRect( rRect );
4095 aRect.Intersection_( getFrameArea() );
4096
4097 rRenderContext.Push( vcl::PushFlags::CLIPREGION );
4098 rRenderContext.SetClipRegion();
4099 const SwPageFrame* pPage = FindPageFrame();
4100
4101 const SwNoTextFrame *pNoText = Lower() && Lower()->IsNoTextFrame()
4102 ? static_cast<const SwNoTextFrame*>(Lower()) : nullptr;
4103
4104 bool bIsChart = false; //#i102950# don't paint additional borders for charts
4105 //check whether we have a chart
4106 if(pNoText)
4107 {
4108 const SwNoTextNode* pNoTNd = dynamic_cast<const SwNoTextNode*>(pNoText->GetNode());
4109 if( pNoTNd )
4110 {
4111 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
4112 if( pOLENd && pOLENd->GetOLEObj().GetObject().IsChart() )
4113 bIsChart = true;
4114 }
4115 }
4116
4117 {
4118 bool bContour = GetFormat()->GetSurround().IsContour();
4119 tools::PolyPolygon aPoly;
4120 if ( bContour )
4121 {
4122 // add 2nd parameter with value <true>
4123 // to indicate that method is called for paint in order to avoid
4124 // load of the intrinsic graphic.
4125 bContour = GetContour( aPoly, true );
4126 }
4127
4128 // #i47804# - distinguish complete background paint
4129 // and margin paint.
4130 // paint complete background for Writer text fly frames
4131 bool bPaintCompleteBack( !pNoText );
4132 // paint complete background for transparent graphic and contour,
4133 // if own background color exists.
4134 const bool bIsGraphicTransparent = pNoText && pNoText->IsTransparent();
4135 if ( !bPaintCompleteBack &&
4136 ( bIsGraphicTransparent|| bContour ) )
4137 {
4138 const SwFlyFrameFormat* pSwFrameFormat = GetFormat();
4139
4140 if (pSwFrameFormat && pSwFrameFormat->supportsFullDrawingLayerFillAttributeSet())
4141 {
4142 // check for transparency
4144
4145 // check if the new fill attributes are used
4146 if(aFillAttributes && aFillAttributes->isUsed())
4147 {
4148 bPaintCompleteBack = true;
4149 }
4150 }
4151 else
4152 {
4153 std::unique_ptr<SvxBrushItem> aBack = GetFormat()->makeBackgroundBrushItem();
4154 // to determine, if background has to be painted, by checking, if
4155 // background color is not COL_TRANSPARENT ("no fill"/"auto fill")
4156 // or a background graphic exists.
4157 bPaintCompleteBack =
4158 aBack->GetColor() != COL_TRANSPARENT ||
4159 aBack->GetGraphicPos() != GPOS_NONE;
4160 }
4161 }
4162 // paint of margin needed.
4163 const bool bPaintMarginOnly( !bPaintCompleteBack &&
4165
4166 // #i47804# - paint background of parent fly frame
4167 // for transparent graphics in layer Hell, if parent fly frame isn't
4168 // in layer Hell. It's only painted the intersection between the
4169 // parent fly frame area and the paint area <aRect>
4171
4172 if (bIsGraphicTransparent &&
4173 GetFormat()->GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::SUBTRACT_FLYS) &&
4174 GetVirtDrawObj()->GetLayer() == rIDDMA.GetHellId() &&
4176 {
4177 const SwFlyFrame* pParentFlyFrame = GetAnchorFrame()->FindFlyFrame();
4178 if ( pParentFlyFrame->GetDrawObj()->GetLayer() !=
4179 rIDDMA.GetHellId() )
4180 {
4181 SwFlyFrame* pOldRet = gProp.pSRetoucheFly2;
4182 gProp.pSRetoucheFly2 = const_cast<SwFlyFrame*>(this);
4183
4184 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pParentFlyFrame );
4185 const SwBorderAttrs &rAttrs = *aAccess.Get();
4186 SwRect aPaintRect( aRect );
4187 aPaintRect.Intersection_( pParentFlyFrame->getFrameArea() );
4188 pParentFlyFrame->PaintSwFrameBackground( aPaintRect, pPage, rAttrs );
4189
4190 gProp.pSRetoucheFly2 = pOldRet;
4191 }
4192 }
4193
4194 if ( bPaintCompleteBack || bPaintMarginOnly )
4195 {
4196 //#24926# JP 01.02.96, PaintBaBo is here partially so PaintSwFrameShadowAndBorder
4197 //receives the original Rect but PaintSwFrameBackground only the limited
4198 //one.
4199
4201 rRenderContext.SetLineColor();
4202
4203 pPage = FindPageFrame();
4204
4205 SwBorderAttrAccess aAccess( SwFrame::GetCache(), static_cast<SwFrame const *>(this) );
4206 const SwBorderAttrs &rAttrs = *aAccess.Get();
4207
4208 // paint background
4209 {
4210 SwRegionRects aRegion( aRect );
4211 // #i80822#
4212 // suppress painting of background in printing area for
4213 // non-transparent graphics.
4214 if ( bPaintMarginOnly ||
4215 ( pNoText && !bIsGraphicTransparent ) )
4216 {
4217 //What we actually want to paint is the small stripe between
4218 //PrtArea and outer border.
4219 SwRect aTmp( getFramePrintArea() ); aTmp += getFrameArea().Pos();
4220 aRegion -= aTmp;
4221 }
4222 if ( bContour )
4223 {
4224 rRenderContext.Push();
4225 // #i80822#
4226 // apply clip region under the same conditions, which are
4227 // used in <SwNoTextFrame::PaintSwFrame(..)> to set the clip region
4228 // for painting the graphic/OLE. Thus, the clip region is
4229 // also applied for the PDF export.
4231
4232 if ( !rRenderContext.GetConnectMetaFile() || !pSh || !pSh->GetWin() )
4233 {
4234 rRenderContext.SetClipRegion(vcl::Region(aPoly));
4235 }
4236
4237 for ( size_t i = 0; i < aRegion.size(); ++i )
4238 {
4239 PaintSwFrameBackground( aRegion[i], pPage, rAttrs, false, true );
4240 }
4241
4242 rRenderContext.Pop();
4243 }
4244 else
4245 {
4246 for ( size_t i = 0; i < aRegion.size(); ++i )
4247 {
4248 PaintSwFrameBackground( aRegion[i], pPage, rAttrs, false, true );
4249 }
4250 }
4251 }
4252
4253 // paint border before painting background
4254 PaintSwFrameShadowAndBorder(rRect, pPage, rAttrs);
4255
4256 rRenderContext.Pop();
4257 }
4258 }
4259
4260 // fly frame will paint it's subsidiary lines and
4261 // the subsidiary lines of its lowers on its own, due to overlapping with
4262 // other fly frames or other objects.
4263 if( gProp.pSGlobalShell->GetWin()
4264 && !bIsChart ) //#i102950# don't paint additional borders for charts
4265 {
4266 bool bSubsLineRectsCreated;
4267 if ( gProp.pSSubsLines )
4268 {
4269 // Lock already existing subsidiary lines
4270 gProp.pSSubsLines->LockLines( true );
4271 bSubsLineRectsCreated = false;
4272 }
4273 else
4274 {
4275 // create new subsidiary lines
4276 gProp.pSSubsLines.reset(new SwSubsRects);
4277 bSubsLineRectsCreated = true;
4278 }
4279
4280 bool bSpecSubsLineRectsCreated;
4281 if ( gProp.pSSpecSubsLines )
4282 {
4283 // Lock already existing special subsidiary lines
4284 gProp.pSSpecSubsLines->LockLines( true );
4285 bSpecSubsLineRectsCreated = false;
4286 }
4287 else
4288 {
4289 // create new special subsidiary lines
4290 gProp.pSSpecSubsLines.reset(new SwSubsRects);
4291 bSpecSubsLineRectsCreated = true;
4292 }
4293 // Add subsidiary lines of fly frame and its lowers
4294 RefreshLaySubsidiary( pPage, aRect );
4295 // paint subsidiary lines of fly frame and its lowers
4296 gProp.pSSpecSubsLines->PaintSubsidiary( &rRenderContext, nullptr, gProp );
4297 gProp.pSSubsLines->PaintSubsidiary(&rRenderContext, gProp.pSLines.get(), gProp);
4298 if ( !bSubsLineRectsCreated )
4299 // unlock subsidiary lines
4300 gProp.pSSubsLines->LockLines( false );
4301 else
4302 {
4303 // delete created subsidiary lines container
4304 gProp.pSSubsLines.reset();
4305 }
4306
4307 if ( !bSpecSubsLineRectsCreated )
4308 // unlock special subsidiary lines
4309 gProp.pSSpecSubsLines->LockLines( false );
4310 else
4311 {
4312 // delete created special subsidiary lines container
4313 gProp.pSSpecSubsLines.reset();
4314 }
4315 }
4316
4317 SwLayoutFrame::PaintSwFrame( rRenderContext, aRect );
4318
4319 Validate();
4320
4321 {
4322 SwTaggedPDFHelper tag(nullptr, nullptr, nullptr, rRenderContext);
4323 // first paint lines added by fly frame paint
4324 // and then unlock other lines.
4325 gProp.pSLines->PaintLines( &rRenderContext, gProp );
4326 gProp.pSLines->LockLines( false );
4327 // have to paint frame borders added in heaven layer here...
4328 ProcessPrimitives(gProp.pBLines->GetBorderLines_Clear());
4329 }
4330
4332
4333 // crossing out for tracked deletion
4334 if ( GetAuthor() != std::string::npos && IsDeleted() )
4335 {
4336 tools::Long startX = aRect.Left( ), endX = aRect.Right();
4337 tools::Long startY = aRect.Top( ), endY = aRect.Bottom();
4339 rRenderContext.DrawLine(Point(startX, startY), Point(endX, endY));
4340 rRenderContext.DrawLine(Point(startX, endY), Point(endX, startY));
4341 }
4342
4343 rRenderContext.Pop();
4344
4345 if ( gProp.pSProgress && pNoText )
4347}
4348
4350{
4351 // Show the un-float button
4352 SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( gProp.pSGlobalShell );
4353 if ( pWrtSh )
4354 {
4356 }
4357}
4358
4360{
4361 SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell);
4362
4363 if (!pWrtSh)
4364 return nullptr;
4365
4366 return &pWrtSh->GetView();
4367}
4368
4370{
4371 // Maybe avoid the dynamic_cast and just use GetActiveWrtShell()
4372 // NO! Multiple windows will not display the highlighting correctly if GetActiveWrtShell is used.
4373 SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell);
4374
4375 if (!pWrtSh)
4376 return;
4377
4378 vcl::RenderContext* pRenderContext = pWrtSh->GetOut();
4379 if (!pRenderContext)
4380 return;
4381
4382 StylesHighlighterColorMap& rParaStylesColorMap
4384
4385 if (rParaStylesColorMap.empty())
4386 return;
4387
4388 // draw styles highlighter
4389 OUString sStyleName = GetTextNodeFirst()->GetTextColl()->GetName();
4390 if (rParaStylesColorMap.find(sStyleName) != rParaStylesColorMap.end())
4391 {
4392 SwRect aFrameAreaRect(getFrameArea());
4393
4394 if (IsRightToLeft())
4395 {
4396 aFrameAreaRect.AddRight(75);
4397 aFrameAreaRect.Left(aFrameAreaRect.Right() + 300);
4398 }
4399 else
4400 {
4401 aFrameAreaRect.AddLeft(-375);
4402 aFrameAreaRect.Right(aFrameAreaRect.Left() + 300);
4403 }
4404
4405 const tools::Rectangle& rRect = aFrameAreaRect.SVRect();
4406
4407 vcl::Font aFont(OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, GetAppLanguage(),
4408 GetDefaultFontFlags::OnlyOne, pRenderContext));
4409 aFont.SetFontSize(Size(0, 140 * pRenderContext->GetDPIScaleFactor()));
4410 aFont.SetUnderline(FontLineStyle::LINESTYLE_NONE);
4411 aFont.SetTransparent(false);
4412 aFont.SetWeight(WEIGHT_NORMAL);
4413 aFont.SetFamily(FontFamily::FAMILY_MODERN);
4414 aFont.SetColor(COL_BLACK);
4415
4416 pRenderContext->Push(vcl::PushFlags::ALL);
4417
4418 pRenderContext->SetFillColor(rParaStylesColorMap[sStyleName].first);
4419 pRenderContext->SetLineColor(rParaStylesColorMap[sStyleName].first);
4420
4421 pRenderContext->DrawRect(rRect);
4422
4423 // draw hatch pattern if paragraph has direct formatting
4425 {
4426 Color aHatchColor(rParaStylesColorMap[sStyleName].first);
4427 // make hatch line color 41% darker than the fill color
4428 aHatchColor.ApplyTintOrShade(-4100);
4429 Hatch aHatch(HatchStyle::Single, aHatchColor, 50, 450_deg10);
4430 pRenderContext->DrawHatch(tools::PolyPolygon(rRect), aHatch);
4431 }
4432
4433 pRenderContext->SetFont(aFont);
4435 pRenderContext->SetTextFillColor(rParaStylesColorMap[sStyleName].first);
4436 pRenderContext->DrawText(rRect, OUString::number(rParaStylesColorMap[sStyleName].second),
4437 DrawTextFlags::Center | DrawTextFlags::VCenter);
4438
4439 pRenderContext->Pop();
4440 }
4441}
4442
4444{
4445 SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(gProp.pSGlobalShell);
4446 if (pWrtSh && pWrtSh->GetViewOptions()->IsShowOutlineContentVisibilityButton())
4448}
4449
4450void SwTabFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
4451{
4452 const SwViewOption* pViewOption = gProp.pSGlobalShell->GetViewOptions();
4453 if (pViewOption->IsTable())
4454 {
4455 // #i29550#
4456 if ( IsCollapsingBorders() )
4457 {
4458 SwBorderAttrAccess aAccess( SwFrame::GetCache(), static_cast<SwFrame const *>(this) );
4459 const SwBorderAttrs &rAttrs = *aAccess.Get();
4460
4461 // paint shadow
4462 if ( rAttrs.GetShadow().GetLocation() != SvxShadowLocation::NONE )
4463 {
4464 SwRect aRect;
4465 ::lcl_CalcBorderRect( aRect, this, rAttrs, true, gProp );
4466 PaintShadow( rRect, aRect, rAttrs );
4467 }
4468
4469 SwTabFramePainter aHelper(*this);
4470 aHelper.PaintLines(rRenderContext, rRect);
4471 }
4472
4473 SwLayoutFrame::PaintSwFrame( rRenderContext, rRect );
4474 }
4475 // #i6467# - no light grey rectangle for page preview
4476 else if ( gProp.pSGlobalShell->GetWin() && !gProp.pSGlobalShell->IsPreview() )
4477 {
4478 // #i6467# - intersect output rectangle with table frame
4479 SwRect aTabRect( getFramePrintArea() );
4480 aTabRect.Pos() += getFrameArea().Pos();
4481 SwRect aTabOutRect( rRect );
4482 aTabOutRect.Intersection( aTabRect );
4483 SwViewOption::DrawRect( &rRenderContext, aTabOutRect, COL_LIGHTGRAY );
4484 }
4485 const_cast<SwTabFrame*>(this)->ResetComplete();
4486}
4487
4501static void lcl_PaintShadow( const SwRect& rRect, SwRect& rOutRect,
4502 const SvxShadowItem& rShadow, const bool bDrawFullShadowRectangle,
4503 const bool bTop, const bool bBottom,
4504 const bool bLeft, const bool bRight,
4505 SwPaintProperties const & properties)
4506{
4507 const tools::Long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth(), properties );
4508 const tools::Long nHeight = ::lcl_AlignHeight( rShadow.GetWidth(), properties );
4509
4510 SwRects aRegion;
4511 SwRect aOut( rOutRect );
4512
4513 switch ( rShadow.GetLocation() )
4514 {
4515 case SvxShadowLocation::BottomRight:
4516 {
4517 if ( bDrawFullShadowRectangle )
4518 {
4519 // draw full shadow rectangle
4520 aOut.Top( rOutRect.Top() + nHeight );
4521 aOut.Left( rOutRect.Left() + nWidth );
4522 aRegion.push_back( aOut );
4523 }
4524 else
4525 {
4526 if( bBottom )
4527 {
4528 aOut.Top( rOutRect.Bottom() - nHeight );
4529 if( bLeft )
4530 aOut.Left( rOutRect.Left() + nWidth );
4531 aRegion.push_back( aOut );
4532 }
4533 if( bRight )
4534 {
4535 aOut.Left( rOutRect.Right() - nWidth );
4536 if( bTop )
4537 aOut.Top( rOutRect.Top() + nHeight );
4538 else
4539 aOut.Top( rOutRect.Top() );
4540 if( bBottom )
4541 aOut.Bottom( rOutRect.Bottom() - nHeight );
4542 aRegion.push_back( aOut );
4543 }
4544 }
4545
4546 if( bRight )
4547 rOutRect.AddRight(- nWidth );
4548 if( bBottom )
4549 rOutRect.AddBottom(- nHeight );
4550 }
4551 break;
4552 case SvxShadowLocation::TopLeft:
4553 {
4554 if ( bDrawFullShadowRectangle )
4555 {
4556 // draw full shadow rectangle
4557 aOut.Bottom( rOutRect.Bottom() - nHeight );
4558 aOut.Right( rOutRect.Right() - nWidth );
4559 aRegion.push_back( aOut );
4560 }
4561 else
4562 {
4563 if( bTop )
4564 {
4565 aOut.Bottom( rOutRect.Top() + nHeight );
4566 if( bRight )
4567 aOut.Right( rOutRect.Right() - nWidth );
4568 aRegion.push_back( aOut );
4569 }
4570 if( bLeft )
4571 {
4572 aOut.Right( rOutRect.Left() + nWidth );
4573 if( bBottom )
4574 aOut.Bottom( rOutRect.Bottom() - nHeight );
4575 else
4576 aOut.Bottom( rOutRect.Bottom() );
4577 if( bTop )
4578 aOut.Top( rOutRect.Top() + nHeight );
4579 aRegion.push_back( aOut );
4580 }
4581 }
4582
4583 if( bLeft )
4584 rOutRect.AddLeft( nWidth );
4585 if( bTop )
4586 rOutRect.AddTop( nHeight );
4587 }
4588 break;
4589 case SvxShadowLocation::TopRight:
4590 {
4591 if ( bDrawFullShadowRectangle )
4592 {
4593 // draw full shadow rectangle
4594 aOut.Bottom( rOutRect.Bottom() - nHeight);
4595 aOut.Left( rOutRect.Left() + nWidth );
4596 aRegion.push_back( aOut );
4597 }
4598 else
4599 {
4600 if( bTop )
4601 {
4602 aOut.Bottom( rOutRect.Top() + nHeight );
4603 if( bLeft )
4604 aOut.Left( rOutRect.Left() + nWidth );
4605 aRegion.push_back( aOut );
4606 }
4607 if( bRight )
4608 {
4609 aOut.Left( rOutRect.Right() - nWidth );
4610 if( bBottom )
4611 aOut.Bottom( rOutRect.Bottom() - nHeight );
4612 else
4613 aOut.Bottom( rOutRect.Bottom() );
4614 if( bTop )
4615 aOut.Top( rOutRect.Top() + nHeight );
4616 aRegion.push_back( aOut );
4617 }
4618 }
4619
4620 if( bRight )
4621 rOutRect.AddRight( - nWidth );
4622 if( bTop )
4623 rOutRect.AddTop( nHeight );
4624 }
4625 break;
4626 case SvxShadowLocation::BottomLeft:
4627 {
4628 if ( bDrawFullShadowRectangle )
4629 {
4630 // draw full shadow rectangle
4631 aOut.Top( rOutRect.Top() + nHeight );
4632 aOut.Right( rOutRect.Right() - nWidth );
4633 aRegion.push_back( aOut );
4634 }
4635 else
4636 {
4637 if( bBottom )
4638 {
4639 aOut.Top( rOutRect.Bottom()- nHeight );
4640 if( bRight )
4641 aOut.Right( rOutRect.Right() - nWidth );
4642 aRegion.push_back( aOut );
4643 }
4644 if( bLeft )
4645 {
4646 aOut.Right( rOutRect.Left() + nWidth );
4647 if( bTop )
4648 aOut.Top( rOutRect.Top() + nHeight );
4649 else
4650 aOut.Top( rOutRect.Top() );
4651 if( bBottom )
4652 aOut.Bottom( rOutRect.Bottom() - nHeight );
4653 aRegion.push_back( aOut );
4654 }
4655 }
4656
4657 if( bLeft )
4658 rOutRect.AddLeft( nWidth );
4659 if( bBottom )
4660 rOutRect.AddBottom( - nHeight );
4661 }
4662 break;
4663 default:
4664 assert(false);
4665 break;
4666 }
4667
4668 vcl::RenderContext *pOut = properties.pSGlobalShell->GetOut();
4669
4670 DrawModeFlags nOldDrawMode = pOut->GetDrawMode();
4671 Color aShadowColor( rShadow.GetColor().GetRGBColor() );
4672 if( !aRegion.empty() && properties.pSGlobalShell->GetWin() &&
4674 {
4675 // In high contrast mode, the output device has already set the
4676 // DrawModeFlags::SettingsFill flag. This causes the SetFillColor function
4677 // to ignore the setting of a new color. Therefore we have to reset
4678 // the drawing mode
4679 pOut->SetDrawMode( DrawModeFlags::Default );
4680 aShadowColor = properties.pSGlobalShell->GetViewOptions()->GetFontColor();
4681 }
4682
4683 if ( pOut->GetFillColor() != aShadowColor )
4684 pOut->SetFillColor( aShadowColor );
4685
4686 pOut->SetLineColor();
4687
4688 pOut->SetDrawMode( nOldDrawMode );
4689
4690 for (const SwRect & rOut : aRegion)
4691 {
4692 aOut = rOut;
4693 if ( rRect.Overlaps( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
4694 {
4695 aOut.Intersection_( rRect );
4696 pOut->DrawRect( aOut.SVRect() );
4697 }
4698 }
4699}
4700
4710void SwFrame::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
4711 const SwBorderAttrs &rAttrs ) const
4712{
4713 SvxShadowItem rShadow = rAttrs.GetShadow();
4714
4715 const bool bCnt = IsContentFrame();
4716 const bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) );
4717 const bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) );
4718
4719 if( IsVertical() )
4720 {
4721 switch( rShadow.GetLocation() )
4722 {
4723 case SvxShadowLocation::BottomRight: rShadow.SetLocation(SvxShadowLocation::BottomLeft); break;
4724 case SvxShadowLocation::TopLeft: rShadow.SetLocation(SvxShadowLocation::TopRight); break;
4725 case SvxShadowLocation::TopRight: rShadow.SetLocation(SvxShadowLocation::BottomRight); break;
4726 case SvxShadowLocation::BottomLeft: rShadow.SetLocation(SvxShadowLocation::TopLeft); break;
4727 default: break;
4728 }
4729 }
4730
4731 // determine, if full shadow rectangle have to be drawn or only two shadow rectangles beside the frame.
4732 // draw full shadow rectangle, if frame background is drawn transparent.
4733 // Status Quo:
4734 // SwLayoutFrame can have transparent drawn backgrounds. Thus,
4735 // "asked" their frame format.
4736 const bool bDrawFullShadowRectangle =
4737 ( IsLayoutFrame() &&
4738 static_cast<const SwLayoutFrame*>(this)->GetFormat()->IsBackgroundTransparent()
4739 );
4740
4741 SwRectFnSet aRectFnSet(this);
4742 ::lcl_ExtendLeftAndRight( rOutRect, *(this), rAttrs, aRectFnSet.FnRect() );
4743
4744 lcl_PaintShadow(rRect, rOutRect, rShadow, bDrawFullShadowRectangle, bTop, bBottom, true, true, gProp);
4745}
4746
4748 const SwRect& rOutRect,
4749 const SwPageFrame * pPage,
4750 const Color *pColor,
4751 const SvxBorderLineStyle nStyle ) const
4752{
4753 if ( !rOutRect.Overlaps( rRect ) )
4754 return;
4755
4756 SwRect aOut( rOutRect );
4757 aOut.Intersection_( rRect );
4758
4759 const SwTabFrame *pTab = IsCellFrame() ? FindTabFrame() : nullptr;
4760 SubColFlags nSubCol = ( IsCellFrame() || IsRowFrame() )
4761 ? SubColFlags::Tab
4762 : ( IsInSct()
4763 ? SubColFlags::Sect
4764 : ( IsInFly() ? SubColFlags::Fly : SubColFlags::Page ) );
4765 if( pColor && gProp.pSGlobalShell->GetWin() &&
4767 {
4769 const SwViewOption *pOpt = pSh->GetViewOptions();
4770 pColor = &pOpt->GetFontColor();
4771 }
4772
4773 if (pPage->GetSortedObjs() &&
4775 {
4776 SwRegionRects aRegion( aOut, 4 );
4778 ::lcl_SubtractFlys( this, pPage, aOut, aRegion, aClipState, gProp );
4779 for ( size_t i = 0; i < aRegion.size(); ++i )
4780 gProp.pSLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol, gProp );
4781 }
4782 else
4783 gProp.pSLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol, gProp );
4784}
4785
4787{
4788 namespace {
4789
4790 class SwBorderRectanglePrimitive2D : public BufferedDecompositionPrimitive2D
4791 {
4792 private:
4795
4801
4802 protected:
4804 virtual void create2DDecomposition(
4805 Primitive2DContainer& rContainer,
4806 const geometry::ViewInformation2D& rViewInformation) const override;
4807
4808 public:
4810 SwBorderRectanglePrimitive2D(
4811 basegfx::B2DHomMatrix aB2DHomMatrix,
4812 const svx::frame::Style& rStyleTop,
4813 const svx::frame::Style& rStyleRight,
4814 const svx::frame::Style& rStyleBottom,
4815 const svx::frame::Style& rStyleLeft);
4816
4818 const basegfx::B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
4819 const svx::frame::Style& getStyleTop() const { return maStyleTop; }
4820 const svx::frame::Style& getStyleRight() const { return maStyleRight; }
4821 const svx::frame::Style& getStyleBottom() const { return maStyleBottom; }
4822 const svx::frame::Style& getStyleLeft() const { return maStyleLeft; }
4823
4825 virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
4826
4828 virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
4829
4831 virtual sal_uInt32 getPrimitive2DID() const override;
4832 };
4833
4834 }
4835
4836 void SwBorderRectanglePrimitive2D::create2DDecomposition(
4837 Primitive2DContainer& rContainer,
4838 const geometry::ViewInformation2D& /*rViewInformation*/) const
4839 {
4840 basegfx::B2DPoint aTopLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 0.0));
4841 basegfx::B2DPoint aTopRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 0.0));
4842 basegfx::B2DPoint aBottomLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 1.0));
4843 basegfx::B2DPoint aBottomRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 1.0));
4844
4845 // prepare SdrFrameBorderDataVector
4847
4848 if(getStyleTop().IsUsed())
4849 {
4850 // move top left/right inwards half border width
4851 basegfx::B2DVector aDown(getB2DHomMatrix() * basegfx::B2DVector(0.0, 1.0));
4852 aDown.setLength(getStyleTop().GetWidth() * 0.5);
4853 aTopLeft += aDown;
4854 aTopRight += aDown;
4855 }
4856
4857 if(getStyleBottom().IsUsed())
4858 {
4859 // move bottom left/right inwards half border width
4860 basegfx::B2DVector aUp(getB2DHomMatrix() * basegfx::B2DVector(0.0, -1.0));
4861 aUp.setLength(getStyleBottom().GetWidth() * 0.5);
4862 aBottomLeft += aUp;
4863 aBottomRight += aUp;
4864 }
4865
4866 if(getStyleLeft().IsUsed())
4867 {
4868 // move left top/bottom inwards half border width
4869 basegfx::B2DVector aRight(getB2DHomMatrix() * basegfx::B2DVector(1.0, 0.0));
4870 aRight.setLength(getStyleLeft().GetWidth() * 0.5);
4871 aTopLeft += aRight;
4872 aBottomLeft += aRight;
4873 }
4874
4875 if(getStyleRight().IsUsed())
4876 {
4877 // move right top/bottom inwards half border width
4878 basegfx::B2DVector aLeft(getB2DHomMatrix() * basegfx::B2DVector(-1.0, 0.0));
4879 aLeft.setLength(getStyleRight().GetWidth() * 0.5);
4880 aTopRight += aLeft;
4881 aBottomRight += aLeft;
4882 }
4883
4884 // go round-robin, from TopLeft to TopRight, down, left and back up. That
4885 // way, the borders will not need to be mirrored in any way
4886 if(getStyleTop().IsUsed())
4887 {
4888 // create BorderPrimitive(s) for top border
4889 const basegfx::B2DVector aVector(aTopRight - aTopLeft);
4890 aData.emplace_back(
4891 aTopLeft,
4892 aVector,
4893 getStyleTop(),
4894 nullptr);
4896
4897 if(getStyleLeft().IsUsed())
4898 {
4899 rInstance.addSdrConnectStyleData(true, getStyleLeft(), basegfx::B2DVector(aBottomLeft - aTopLeft), false);
4900 }
4901
4902 if(getStyleRight().IsUsed())
4903 {
4904 rInstance.addSdrConnectStyleData(false, getStyleRight(), basegfx::B2DVector(aBottomRight - aTopRight), false);
4905 }
4906 }
4907
4908 if(getStyleRight().IsUsed())
4909 {
4910 // create BorderPrimitive(s) for right border
4911 const basegfx::B2DVector aVector(aBottomRight - aTopRight);
4912 aData.emplace_back(
4913 aTopRight,
4914 aVector,
4915 getStyleRight(),
4916 nullptr);
4918
4919 if(getStyleTop().IsUsed())
4920 {
4921 rInstance.addSdrConnectStyleData(true, getStyleTop(), basegfx::B2DVector(aTopLeft - aTopRight), false);
4922 }
4923
4924 if(getStyleBottom().IsUsed())
4925 {
4926 rInstance.addSdrConnectStyleData(false, getStyleBottom(), basegfx::B2DVector(aBottomLeft - aBottomRight), false);
4927 }
4928 }
4929
4930 if(getStyleBottom().IsUsed())
4931 {
4932 // create BorderPrimitive(s) for bottom border
4933 const basegfx::B2DVector aVector(aBottomLeft - aBottomRight);
4934 aData.emplace_back(
4935 aBottomRight,
4936 aVector,
4937 getStyleBottom(),
4938 nullptr);
4940
4941 if(getStyleRight().IsUsed())
4942 {
4943 rInstance.addSdrConnectStyleData(true, getStyleRight(), basegfx::B2DVector(aTopRight - aBottomRight), false);
4944 }
4945
4946 if(getStyleLeft().IsUsed())
4947 {
4948 rInstance.addSdrConnectStyleData(false, getStyleLeft(), basegfx::B2DVector(aTopLeft - aBottomLeft), false);
4949 }
4950 }
4951
4952 if(getStyleLeft().IsUsed())
4953 {
4954 // create BorderPrimitive(s) for left border
4955 const basegfx::B2DVector aVector(aTopLeft - aBottomLeft);
4956 aData.emplace_back(
4957 aBottomLeft,
4958 aVector,
4959 getStyleLeft(),
4960 nullptr);
4962
4963 if(getStyleBottom().IsUsed())
4964 {
4965 rInstance.addSdrConnectStyleData(true, getStyleBottom(), basegfx::B2DVector(aBottomRight - aBottomLeft), false);
4966 }
4967
4968 if(getStyleTop().IsUsed())
4969 {
4970 rInstance.addSdrConnectStyleData(false, getStyleTop(), basegfx::B2DVector(aTopRight - aTopLeft), false);
4971 }
4972 }
4973
4974 // create instance of SdrFrameBorderPrimitive2D if
4975 // SdrFrameBorderDataVector is used
4976 if(!aData.empty())
4977 {
4978 rContainer.append(
4981 std::move(aData),
4982 true))); // force visualization to minimal one discrete unit (pixel)
4983 }
4984 }
4985
4986 SwBorderRectanglePrimitive2D::SwBorderRectanglePrimitive2D(
4987 basegfx::B2DHomMatrix aB2DHomMatrix,
4988 const svx::frame::Style& rStyleTop,
4989 const svx::frame::Style& rStyleRight,
4990 const svx::frame::Style& rStyleBottom,
4991 const svx::frame::Style& rStyleLeft)
4992 : maB2DHomMatrix(std::move(aB2DHomMatrix)),
4993 maStyleTop(rStyleTop),
4994 maStyleRight(rStyleRight),
4995 maStyleBottom(rStyleBottom),
4996 maStyleLeft(rStyleLeft)
4997 {
4998 }
4999
5000 bool SwBorderRectanglePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
5001 {
5002 if(BasePrimitive2D::operator==(rPrimitive))
5003 {
5004 const SwBorderRectanglePrimitive2D& rCompare = static_cast<const SwBorderRectanglePrimitive2D&>(rPrimitive);
5005
5006 return (getB2DHomMatrix() == rCompare.getB2DHomMatrix() &&
5007 getStyleTop() == rCompare.getStyleTop() &&
5008 getStyleRight() == rCompare.getStyleRight() &&
5009 getStyleBottom() == rCompare.getStyleBottom() &&
5010 getStyleLeft() == rCompare.getStyleLeft());
5011 }
5012
5013 return false;
5014 }
5015
5016 basegfx::B2DRange SwBorderRectanglePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
5017 {
5018 basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
5019
5020 aRetval.transform(getB2DHomMatrix());
5021 return aRetval;
5022 }
5023
5024 // provide unique ID
5025 sal_uInt32 SwBorderRectanglePrimitive2D::getPrimitive2DID() const
5026 {
5028 }
5029
5030} // end of namespace drawinglayer::primitive2d
5031
5032namespace {
5033
5034editeng::SvxBorderLine const * get_ptr(std::optional<editeng::SvxBorderLine> const & opt) {
5035 return opt ? &*opt : nullptr;
5036}
5037
5038}
5039
5041 const SwFont& rFont,
5042 const SwRect& rPaintArea,
5043 const bool bVerticalLayout,
5044 const bool bVerticalLayoutLRBT,
5045 const bool bJoinWithPrev,
5046 const bool bJoinWithNext )
5047{
5048 SwRect aAlignedRect(rPaintArea);
5049 SwAlignRect(aAlignedRect, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut());
5050
5051 bool bTop = true;
5052 bool bBottom = true;
5053 bool bLeft = true;
5054 bool bRight = true;
5055
5056 switch (rFont.GetOrientation(bVerticalLayout, bVerticalLayoutLRBT).get())
5057 {
5058 case 0 :
5059 bLeft = !bJoinWithPrev;
5060 bRight = !bJoinWithNext;
5061 break;
5062 case 900 :
5063 bBottom = !bJoinWithPrev;
5064 bTop = !bJoinWithNext;
5065 break;
5066 case 1800 :
5067 bRight = !bJoinWithPrev;
5068 bLeft = !bJoinWithNext;
5069 break;
5070 case 2700 :
5071 bTop = !bJoinWithPrev;
5072 bBottom = !bJoinWithNext;
5073 break;
5074 }
5075
5076 // Paint shadow (reduce painting rect)
5077 {
5078 const SvxShadowItem aShadow(
5079 0, &rFont.GetShadowColor(), rFont.GetShadowWidth(),
5080 rFont.GetAbsShadowLocation(bVerticalLayout, bVerticalLayoutLRBT));
5081
5082 if( aShadow.GetLocation() != SvxShadowLocation::NONE )
5083 {
5084 lcl_PaintShadow( rPaintArea, aAlignedRect, aShadow,
5085 false, bTop, bBottom, bLeft, bRight, gProp);
5086 }
5087 }
5088
5089 const basegfx::B2DHomMatrix aBorderTransform(
5091 aAlignedRect.Width(), aAlignedRect.Height(),
5092 aAlignedRect.Left(), aAlignedRect.Top()));
5093 const svx::frame::Style aStyleTop(
5094 bTop ? get_ptr(rFont.GetAbsTopBorder(bVerticalLayout, bVerticalLayoutLRBT)) : nullptr,
5095 1.0);
5096 const svx::frame::Style aStyleRight(
5097 bRight ? get_ptr(rFont.GetAbsRightBorder(bVerticalLayout, bVerticalLayoutLRBT)) : nullptr,
5098 1.0);
5099 const svx::frame::Style aStyleBottom(
5100 bBottom ? get_ptr(rFont.GetAbsBottomBorder(bVerticalLayout, bVerticalLayoutLRBT))
5101 : nullptr,
5102 1.0);
5103 const svx::frame::Style aStyleLeft(
5104 bLeft ? get_ptr(rFont.GetAbsLeftBorder(bVerticalLayout, bVerticalLayoutLRBT)) : nullptr,
5105 1.0);
5107
5108 aBorderLineTarget.append(
5110 new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D(
5111 aBorderTransform,
5112 aStyleTop,
5113 aStyleRight,
5114 aStyleBottom,
5115 aStyleLeft)));
5116 gProp.pBLines->AddBorderLines(std::move(aBorderLineTarget));
5117}
5118
5120static const SwFrame* lcl_HasNextCell( const SwFrame& rFrame )
5121{
5122 OSL_ENSURE( rFrame.IsCellFrame(),
5123 "lcl_HasNextCell( const SwFrame& rFrame ) should be called with SwCellFrame" );
5124
5125 const SwFrame* pTmpFrame = &rFrame;
5126 do
5127 {
5128 if ( pTmpFrame->GetNext() )
5129 return pTmpFrame->GetNext();
5130
5131 pTmpFrame = pTmpFrame->GetUpper()->GetUpper();
5132 }
5133 while ( pTmpFrame->IsCellFrame() );
5134
5135 return nullptr;
5136}
5137
5159static const SwFrame* lcl_GetCellFrameForBorderAttrs( const SwFrame* _pCellFrame,
5160 const SwBorderAttrs& _rCellBorderAttrs,
5161 const bool _bTop )
5162{
5163 OSL_ENSURE( _pCellFrame, "No cell frame available, dying soon" );
5164
5165 // determine, if cell frame is at bottom/top border of a table frame and
5166 // the table frame has/is a follow.
5167 const SwFrame* pTmpFrame = _pCellFrame;
5168 bool bCellAtBorder = true;
5169 bool bCellAtLeftBorder = !_pCellFrame->GetPrev();
5170 bool bCellAtRightBorder = !_pCellFrame->GetNext();
5171 while( !pTmpFrame->IsRowFrame() || !pTmpFrame->GetUpper()->IsTabFrame() )
5172 {
5173 pTmpFrame = pTmpFrame->GetUpper();
5174 if ( pTmpFrame->IsRowFrame() &&
5175 (_bTop ? pTmpFrame->GetPrev() : pTmpFrame->GetNext())
5176 )
5177 {
5178 bCellAtBorder = false;
5179 }
5180 if ( pTmpFrame->IsCellFrame() )
5181 {
5182 if ( pTmpFrame->GetPrev() )
5183 {
5184 bCellAtLeftBorder = false;
5185 }
5186 if ( pTmpFrame->GetNext() )
5187 {
5188 bCellAtRightBorder = false;
5189 }
5190 }
5191 }
5192 OSL_ENSURE( pTmpFrame && pTmpFrame->IsRowFrame(), "No RowFrame available" );
5193
5194 const SwLayoutFrame* pParentRowFrame = static_cast<const SwLayoutFrame*>(pTmpFrame);
5195 const SwTabFrame* pParentTabFrame =
5196 static_cast<const SwTabFrame*>(pParentRowFrame->GetUpper());
5197
5198 const bool bCellNeedsAttribute = bCellAtBorder &&
5199 ( _bTop ?
5200 // bCellInFirstRowWithMaster
5201 ( !pParentRowFrame->GetPrev() &&
5202 pParentTabFrame->IsFollow() &&
5203 0 == pParentTabFrame->GetTable()->GetRowsToRepeat() ) :
5204 // bCellInLastRowWithFollow
5205 ( !pParentRowFrame->GetNext() &&
5206 pParentTabFrame->GetFollow() )
5207 );
5208
5209 const SwFrame* pRet = _pCellFrame;
5210 if ( bCellNeedsAttribute )
5211 {
5212 // determine, if cell frame has no borders inside the table.
5213 const SwFrame* pNextCell = nullptr;
5214 bool bNoBordersInside = false;
5215
5216 if ( bCellAtLeftBorder && ( nullptr != ( pNextCell = lcl_HasNextCell( *_pCellFrame ) ) ) )
5217 {
5218 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pNextCell );
5219 const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
5220 const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
5221 bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
5222 bNoBordersInside =
5223 ( !rBorderBox.GetTop() || !pParentRowFrame->GetPrev() ) &&
5224 !rBorderBox.GetLeft() &&
5225 ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
5226 ( !rBorderBox.GetBottom() || !pParentRowFrame->GetNext() );
5227 }
5228 else
5229 {
5230 const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
5231 bNoBordersInside =
5232 ( !rBorderBox.GetTop() || !pParentRowFrame->GetPrev() ) &&
5233 ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) &&
5234 ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
5235 ( !rBorderBox.GetBottom() || !pParentRowFrame->GetNext() );
5236 }
5237
5238 if ( bNoBordersInside )
5239 {
5240 if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
5241 {
5242 //-hack
5243 // Cell frame has no top border and no border inside the table, but
5244 // it is at the top border of a table frame, which is a follow.
5245 // Thus, use border attributes of cell frame in first row of complete table.
5246 // First, determine first table frame of complete table.
5247 SwTabFrame* pMasterTabFrame = pParentTabFrame->FindMaster( true );
5248 // determine first row of complete table.
5249 const SwFrame* pFirstRow = pMasterTabFrame->GetLower();
5250 // return first cell in first row
5251 SwFrame* pLowerCell = const_cast<SwFrame*>(pFirstRow->GetLower());
5252 while ( !pLowerCell->IsCellFrame() ||
5253 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrame() )
5254 )
5255 {
5256 pLowerCell = pLowerCell->GetLower();
5257 }
5258 OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrame(), "No CellFrame available" );
5259 pRet = pLowerCell;
5260 }
5261 else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
5262 {
5263 //-hack
5264 // Cell frame has no bottom border and no border inside the table,
5265 // but it is at the bottom border of a table frame, which has a follow.
5266 // Thus, use border attributes of cell frame in last row of complete table.
5267 // First, determine last table frame of complete table.
5268 SwTabFrame* pLastTabFrame = const_cast<SwTabFrame*>(pParentTabFrame->GetFollow());
5269 while ( pLastTabFrame->GetFollow() )
5270 {
5271 pLastTabFrame = pLastTabFrame->GetFollow();
5272 }
5273 // determine last row of complete table.
5274 SwFrame* pLastRow = pLastTabFrame->GetLastLower();
5275 // return first bottom border cell in last row
5276 SwFrame* pLowerCell = pLastRow->GetLower();
5277 while ( !pLowerCell->IsCellFrame() ||
5278 ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrame() )
5279 )
5280 {
5281 if ( pLowerCell->IsRowFrame() )
5282 {
5283 while ( pLowerCell->GetNext() )
5284 {
5285 pLowerCell = pLowerCell->GetNext();
5286 }
5287 }
5288 pLowerCell = pLowerCell->GetLower();
5289 }
5290 OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrame(), "No CellFrame available" );
5291 pRet = pLowerCell;
5292 }
5293 }
5294 }
5295
5296 return pRet;
5297}
5298
5299std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> SwFrame::CreateProcessor2D( ) const
5300{
5301 basegfx::B2DRange aViewRange;
5302
5303 SdrPage *pDrawPage = getRootFrame()->GetCurrShell()->Imp()->GetPageView()->GetPage();
5305 aNewViewInfos.setViewTransformation(getRootFrame()->GetCurrShell()->GetOut()->GetViewTransformation());
5306 aNewViewInfos.setViewport(aViewRange);
5307 aNewViewInfos.setVisualizedPage(GetXDrawPageForSdrPage( pDrawPage ));
5308
5310 *getRootFrame()->GetCurrShell()->GetOut(),
5311 aNewViewInfos );
5312}
5313
5315{
5316 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D = CreateProcessor2D();
5317 if ( pProcessor2D )
5318 {
5319 pProcessor2D->process( rSequence );
5320 }
5321}
5322
5325 const SwRect& rRect,
5326 const SwPageFrame* /*pPage*/,
5327 const SwBorderAttrs& rAttrs) const
5328{
5329 // There's nothing (Row,Body,Footnote,Root,Column,NoText) need to do here
5331 return;
5332
5333 if (IsCellFrame() && !gProp.pSGlobalShell->GetViewOptions()->IsTable())
5334 return;
5335
5336 // #i29550#
5337 if ( IsTabFrame() || IsCellFrame() || IsRowFrame() )
5338 {
5339 const SwTabFrame* pTabFrame = FindTabFrame();
5340 if ( pTabFrame->IsCollapsingBorders() )
5341 return;
5342
5343 if ( pTabFrame->GetTable()->IsNewModel() && ( !IsCellFrame() || IsCoveredCell() ) )
5344 return;
5345 }
5346
5347 const bool bLine = rAttrs.IsLine();
5348 const bool bShadow = rAttrs.GetShadow().GetLocation() != SvxShadowLocation::NONE;
5349
5350 // - flag to control,
5351 //-hack has to be used.
5352 const bool bb4779636HackActive = true;
5353
5354 const SwFrame* pCellFrameForBottomBorderAttrs = nullptr;
5355 const SwFrame* pCellFrameForTopBorderAttrs = nullptr;
5356 bool bFoundCellForTopOrBorderAttrs = false;
5357 if ( bb4779636HackActive && IsCellFrame() )
5358 {
5359 pCellFrameForBottomBorderAttrs = lcl_GetCellFrameForBorderAttrs( this, rAttrs, false );
5360 if ( pCellFrameForBottomBorderAttrs != this )
5361 bFoundCellForTopOrBorderAttrs = true;
5362 pCellFrameForTopBorderAttrs = lcl_GetCellFrameForBorderAttrs( this, rAttrs, true );
5363 if ( pCellFrameForTopBorderAttrs != this )
5364 bFoundCellForTopOrBorderAttrs = true;
5365 }
5366
5367 // - add condition <bFoundCellForTopOrBorderAttrs>
5368 //-hack
5369 if ( !(bLine || bShadow || bFoundCellForTopOrBorderAttrs) )
5370 return;
5371
5372 //If the rectangle is completely inside the PrtArea, no border needs to
5373 //be painted.
5374 //For the PrtArea the aligned value needs to be used, otherwise it could
5375 //happen, that some parts won't be processed.
5376 SwRect aRect( getFramePrintArea() );
5377 aRect += getFrameArea().Pos();
5378 ::SwAlignRect( aRect, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
5379 // new local boolean variable in order to
5380 // suspend border paint under special cases - see below.
5381 // NOTE: This is a fix for the implementation of feature #99657#.
5382 bool bDrawOnlyShadowForTransparentFrame = false;
5383 if ( aRect.Contains( rRect ) )
5384 {
5385 // paint shadow, if background is transparent.
5386 // Because of introduced transparent background for fly frame #99657#,
5387 // the shadow have to be drawn if the background is transparent,
5388 // in spite the fact that the paint rectangle <rRect> lies fully
5389 // in the printing area.
5390 // NOTE to chosen solution:
5391 // On transparent background, continue processing, but suspend
5392 // drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
5393 // to true.
5394 if ( IsLayoutFrame() &&
5395 static_cast<const SwLayoutFrame*>(this)->GetFormat()->IsBackgroundTransparent() )
5396 {
5397 bDrawOnlyShadowForTransparentFrame = true;
5398 }
5399 else
5400 {
5401 return;
5402 }
5403 }
5404
5405 ::lcl_CalcBorderRect( aRect, this, rAttrs, true, gProp );
5406 rAttrs.SetGetCacheLine( true );
5407
5408 if(bShadow)
5409 {
5410 PaintShadow(rRect, aRect, rAttrs);
5411 }
5412
5413 // suspend drawing of border
5414 // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
5415 // - add condition <bFoundCellForTopOrBorderAttrs>
5416 //-hack.
5417 if((bLine || bFoundCellForTopOrBorderAttrs) && !bDrawOnlyShadowForTransparentFrame)
5418 {
5419 // define SvxBorderLine(s) to use
5420 const SvxBoxItem& rBox(rAttrs.GetBox());
5421 const SvxBorderLine* pLeftBorder(rBox.GetLeft());
5422 const SvxBorderLine* pRightBorder(rBox.GetRight());
5423 const SvxBorderLine* pTopBorder(rBox.GetTop());
5424 const SvxBorderLine* pBottomBorder(rBox.GetBottom());
5425
5426 // if R2L, exchange Right/Left
5427 const bool bR2L(IsCellFrame() && IsRightToLeft());
5428
5429 if(bR2L)
5430 {
5431 std::swap(pLeftBorder, pRightBorder);
5432 }
5433
5434 // if ContentFrame and joined Prev/Next, reset top/bottom as needed
5435 if(IsContentFrame())
5436 {
5437 const SwFrame* pDirRefFrame(IsCellFrame() ? FindTabFrame() : this);
5438 const SwRectFnSet aRectFnSet(pDirRefFrame);
5439 const SwRectFn& _rRectFn(aRectFnSet.FnRect());
5440
5441 if(rAttrs.JoinedWithPrev(*this))
5442 {
5443 // tdf#115296 re-add adaptation of vert distance to close the evtl.
5444 // existing gap to previous frame
5445 const SwFrame* pPrevFrame(GetPrev());
5446 (aRect.*_rRectFn->fnSetTop)( (pPrevFrame->*_rRectFn->fnGetPrtBottom)() );
5447
5448 // ...and disable top border paint/creation
5449 pTopBorder = nullptr;
5450 }
5451
5452 if(rAttrs.JoinedWithNext(*this))
5453 {
5454 // tdf#115296 re-add adaptation of vert distance to close the evtl.
5455 // existing gap to next frame
5456 const SwFrame* pNextFrame(GetNext());
5457 (aRect.*_rRectFn->fnSetBottom)( (pNextFrame->*_rRectFn->fnGetPrtTop)() );
5458
5459 // ...and disable bottom border paint/creation
5460 pBottomBorder = nullptr;
5461 }
5462 }
5463
5464 // necessary to replace TopBorder?
5465 if((!IsContentFrame() || rAttrs.GetTopLine(*this)) && IsCellFrame() && pCellFrameForTopBorderAttrs != this)
5466 {
5467 SwBorderAttrAccess aAccess(SwFrame::GetCache(), pCellFrameForTopBorderAttrs);
5468 pTopBorder = aAccess.Get()->GetBox().GetTop();
5469 }
5470
5471 // necessary to replace BottomBorder?
5472 if((!IsContentFrame() || rAttrs.GetBottomLine(*this)) && IsCellFrame() && pCellFrameForBottomBorderAttrs != this)
5473 {
5474 SwBorderAttrAccess aAccess(SwFrame::GetCache(), pCellFrameForBottomBorderAttrs);
5475 pBottomBorder = aAccess.Get()->GetBox().GetBottom();
5476 }
5477
5478 bool bWordBorder = false;
5479 SwViewShell* pShell = getRootFrame()->GetCurrShell();
5480 if (pShell)
5481 {
5482 const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess();
5483 bWordBorder = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP);
5484 }
5485 bool bInWordTableCell = IsContentFrame() && GetUpper()->IsCellFrame() && bWordBorder;
5486 if (bInWordTableCell)
5487 {
5488 // Compat mode: don't paint bottom border if we know the bottom of the content was cut
5489 // off.
5490 auto pContentFrame = static_cast<const SwContentFrame*>(this);
5491 if (pContentFrame->IsUndersized())
5492 {
5493 pBottomBorder = nullptr;
5494 }
5495 }
5496
5497 if(nullptr != pLeftBorder || nullptr != pRightBorder || nullptr != pTopBorder || nullptr != pBottomBorder)
5498 {
5499 // now we have all SvxBorderLine(s) sorted out, create geometry
5500 const basegfx::B2DHomMatrix aBorderTransform(
5502 aRect.Width(), aRect.Height(),
5503 aRect.Left(), aRect.Top()));
5504 const svx::frame::Style aStyleTop(pTopBorder, 1.0);
5505 svx::frame::Style aStyleRight(pRightBorder, 1.0);
5506
5507 // Right/bottom page borders are always mirrored in Word.
5508 if (IsPageFrame() && bWordBorder)
5509 {
5510 aStyleRight.MirrorSelf();
5511 }
5512
5513 svx::frame::Style aStyleBottom(pBottomBorder, 1.0);
5514
5515 if (IsPageFrame() && bWordBorder)
5516 {
5517 aStyleBottom.MirrorSelf();
5518 }
5519
5520 const svx::frame::Style aStyleLeft(pLeftBorder, 1.0);
5522
5524 new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D(
5525 aBorderTransform,
5526 aStyleTop,
5527 aStyleRight,
5528 aStyleBottom,
5529 aStyleLeft));
5530
5531 if (bInWordTableCell)
5532 {
5533 // Compat mode: cut off the borders which are outside of our own area.
5534 const SwRect& rClip = getFrameArea();
5535 basegfx::B2DRectangle aClip(rClip.Left(), rClip.Top(), rClip.Right(),
5536 rClip.Bottom());
5537 basegfx::B2DPolyPolygon aPolyPolygon(
5540 new drawinglayer::primitive2d::MaskPrimitive2D(std::move(aPolyPolygon), { aRetval }));
5541 aRetval = xClipped;
5542 }
5543
5544 aBorderLineTarget.append(aRetval);
5545 gProp.pBLines->AddBorderLines(std::move(aBorderLineTarget));
5546 }
5547 }
5548
5549 rAttrs.SetGetCacheLine( false );
5550}
5551
5559 const SwRect& rRect,
5560 const SwPageFrame* pPage,
5561 const SwBorderAttrs&) const
5562{
5563 //If the rectangle is completely inside the PrtArea, no border needs to
5564 //be painted.
5565 SwRect aRect( getFramePrintArea() );
5566 aRect.Pos() += getFrameArea().Pos();
5567 if ( !aRect.Contains( rRect ) )
5568 PaintLine( rRect, pPage );
5569}
5570
5573 const SwPageFrame *pPage ) const
5574{
5575 //The length of the line is derived from the percentual indication on the
5576 //PageDesc. The position is also stated on the PageDesc.
5577 //The pen can directly be taken from the PageDesc.
5578
5579 if ( !pPage )
5580 pPage = FindPageFrame();
5581 const SwPageFootnoteInfo &rInf = pPage->GetPageDesc()->GetFootnoteInfo();
5582
5583 SwRectFnSet aRectFnSet(this);
5584 SwTwips nPrtWidth = aRectFnSet.GetWidth(getFramePrintArea());
5585 Fraction aFract( nPrtWidth, 1 );
5586 aFract *= rInf.GetWidth();
5587 const SwTwips nWidth = static_cast<tools::Long>(aFract);
5588
5589 SwTwips nX = aRectFnSet.GetPrtLeft(*this);
5590 switch ( rInf.GetAdj() )
5591 {
5592 case css::text::HorizontalAdjust_CENTER:
5593 nX += nPrtWidth/2 - nWidth/2; break;
5594 case css::text::HorizontalAdjust_RIGHT:
5595 nX += nPrtWidth - nWidth; break;
5596 case css::text::HorizontalAdjust_LEFT:
5597 /* do nothing */; break;
5598 default:
5599 SAL_WARN("sw.core", "New adjustment for footnote lines?");
5600 assert(false);
5601 }
5603 const SwRect aLineRect = aRectFnSet.IsVert() ?
5605 nX), Size( nLineWidth, nWidth ) )
5606 : SwRect( Point( nX, getFrameArea().Pos().Y() + rInf.GetTopDist() ),
5607 Size( nWidth, rInf.GetLineWidth()));
5608 if ( aLineRect.HasArea() && rInf.GetLineStyle() != SvxBorderLineStyle::NONE)
5609 PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor(),
5610 rInf.GetLineStyle() );
5611}
5612
5614{
5615 (void)xmlTextWriterStartElement(writer, reinterpret_cast<const xmlChar*>("ftncont"));
5616 dumpAsXmlAttributes(writer);
5617
5618 (void)xmlTextWriterStartElement(writer, BAD_CAST("infos"));
5619 dumpInfosAsXml(writer);
5620 (void)xmlTextWriterEndElement(writer);
5621 dumpChildrenAsXml(writer);
5622
5623 (void)xmlTextWriterEndElement(writer);
5624}
5625
5627void SwLayoutFrame::PaintColLines( const SwRect &rRect, const SwFormatCol &rFormatCol,
5628 const SwPageFrame *pPage ) const
5629{
5630 const SwFrame *pCol = Lower();
5631 if ( !pCol || !pCol->IsColumnFrame() )
5632 return;
5633
5634 SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? (pCol->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
5635
5636 SwRect aLineRect = getFramePrintArea();
5637 aLineRect += getFrameArea().Pos();
5638
5639 SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFormatCol.GetLineHeight())
5640 / 100 - (aLineRect.*fnRect->fnGetHeight)();
5641 SwTwips nBottom = 0;
5642
5643 switch ( rFormatCol.GetLineAdj() )
5644 {
5645 case COLADJ_CENTER:
5646 nBottom = nTop / 2; nTop -= nBottom; break;
5647 case COLADJ_TOP:
5648 nBottom = nTop; nTop = 0; break;
5649 case COLADJ_BOTTOM:
5650 break;
5651 default:
5652 OSL_ENSURE( false, "New adjustment for column lines?" );
5653 }
5654
5655 if( nTop )
5656 (aLineRect.*fnRect->fnSubTop)( nTop );
5657 if( nBottom )
5658 (aLineRect.*fnRect->fnAddBottom)( nBottom );
5659
5660 SwTwips nPenHalf = rFormatCol.GetLineWidth();
5661 (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
5662 nPenHalf /= 2;
5663
5664 //We need to be a bit generous here, to not lose something.
5665 SwRect aRect( rRect );
5666 (aRect.*fnRect->fnSubLeft)( nPenHalf + gProp.nSPixelSzW );
5667 (aRect.*fnRect->fnAddRight)( nPenHalf + gProp.nSPixelSzW );
5668 SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
5669 while ( pCol->GetNext() )
5670 {
5671 (aLineRect.*fnRect->fnSetPosX)
5672 ( (pCol->getFrameArea().*fnGetX)() - nPenHalf );
5673 if ( aRect.Overlaps( aLineRect ) )
5674 PaintBorderLine( aRect, aLineRect , pPage, &rFormatCol.GetLineColor(),
5675 rFormatCol.GetLineStyle() );
5676 pCol = pCol->GetNext();
5677 }
5678}
5679
5680void SwPageFrame::PaintGrid( OutputDevice const * pOut, SwRect const &rRect ) const
5681{
5682 if( !m_bHasGrid || gProp.pSRetoucheFly || gProp.pSRetoucheFly2 )
5683 return;
5684 SwTextGridItem const*const pGrid(GetGridItem(this));
5685 if( !(pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
5686 pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() )) )
5687 return;
5688
5689 const SwLayoutFrame* pBody = FindBodyCont();
5690 if( !pBody )
5691 return;
5692
5693 SwRect aGrid( pBody->getFramePrintArea() );
5694 aGrid += pBody->getFrameArea().Pos();
5695
5696 SwRect aInter( aGrid );
5697 aInter.Intersection( rRect );
5698 if( !aInter.HasArea() )
5699 return;
5700
5701 bool bGrid = pGrid->GetRubyTextBelow();
5702 bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
5703 tools::Long nGrid = pGrid->GetBaseHeight();
5704 const SwDoc* pDoc = GetFormat()->GetDoc();
5705 tools::Long nGridWidth = GetGridWidth(*pGrid, *pDoc);
5706 tools::Long nRuby = pGrid->GetRubyHeight();
5707 tools::Long nSum = nGrid + nRuby;
5708 const Color *pCol = &pGrid->GetColor();
5709
5710 SwTwips nRight = aInter.Left() + aInter.Width();
5711 SwTwips nBottom = aInter.Top() + aInter.Height();
5712 if( IsVertical() )
5713 {
5714 SwTwips nOrig = aGrid.Left() + aGrid.Width();
5715 SwTwips nY = nOrig + nSum *
5716 ( ( nOrig - aInter.Left() ) / nSum );
5717 SwRect aTmp( Point( nY, aInter.Top() ),
5718 Size( 1, aInter.Height() ) );
5719 SwTwips nX = aGrid.Top() + nGrid *
5720 ( ( aInter.Top() - aGrid.Top() )/ nGrid );
5721 if( nX < aInter.Top() )
5722 nX += nGrid;
5723 SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
5724 bool bLeft = aGrid.Top() >= aInter.Top();
5725 bool bRight = nGridBottom <= nBottom;
5726 bool bBorder = bLeft || bRight;
5727 while( nY > nRight )
5728 {
5729 aTmp.Pos().setX( nY );
5730 if( bGrid )
5731 {
5732 nY -= nGrid;
5733 SwTwips nPosY = std::max( SwTwips(aInter.Left()), nY );
5734 SwTwips nHeight = std::min(nRight, SwTwips(aTmp.Pos().X()))-nPosY;
5735 if( nHeight > 0 )
5736 {
5737 if( bCell )
5738 {
5739 SwRect aVert( Point( nPosY, nX ),
5740 Size( nHeight, 1 ) );
5741 while( aVert.Top() <= nBottom )
5742 {
5743 PaintBorderLine(rRect,aVert,this,pCol);
5744 aVert.Pos().AdjustY(nGrid );
5745 }
5746 }
5747 else if( bBorder )
5748 {
5749 SwRect aVert( Point( nPosY, aGrid.Top() ),
5750 Size( nHeight, 1 ) );
5751 if( bLeft )
5752 PaintBorderLine(rRect,aVert,this,pCol);
5753 if( bRight )
5754 {
5755 aVert.Pos().setY( nGridBottom );
5756 PaintBorderLine(rRect,aVert,this,pCol);
5757 }
5758 }
5759 }
5760 }
5761 else
5762 {
5763 nY -= nRuby;
5764 if( bBorder )
5765 {
5766 SwTwips nPos = std::max( SwTwips(aInter.Left()), nY );
5767 SwTwips nW = std::min(nRight, SwTwips(aTmp.Pos().X())) - nPos;
5768 SwRect aVert( Point( nPos, aGrid.Top() ),
5769 Size( nW, 1 ) );
5770 if( nW > 0 )
5771 {
5772 if( bLeft )
5773 PaintBorderLine(rRect,aVert,this,pCol);
5774 if( bRight )
5775 {
5776 aVert.Pos().setY( nGridBottom );
5777 PaintBorderLine(rRect,aVert,this,pCol);
5778 }
5779 }
5780 }
5781 }
5782 bGrid = !bGrid;
5783 }
5784 while( nY >= aInter.Left() )
5785 {
5786 aTmp.Pos().setX( nY );
5787 PaintBorderLine( rRect, aTmp, this, pCol);
5788 if( bGrid )
5789 {
5790 nY -= nGrid;
5791 SwTwips nHeight = aTmp.Pos().X()
5792 - std::max(SwTwips(aInter.Left()), nY );
5793 if( nHeight > 0 )
5794 {
5795 if( bCell )
5796 {
5797 SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5798 nX ), Size( nHeight, 1 ) );
5799 while( aVert.Top() <= nBottom )
5800 {
5801 PaintBorderLine(rRect,aVert,this,pCol);
5802 aVert.Pos().AdjustY(nGrid );
5803 }
5804 }
5805 else if( bBorder )
5806 {
5807 SwRect aVert( Point(aTmp.Pos().X()-nHeight,
5808 aGrid.Top() ), Size( nHeight, 1 ) );
5809 if( bLeft )
5810 PaintBorderLine(rRect,aVert,this,pCol);
5811 if( bRight )
5812 {
5813 aVert.Pos().setY( nGridBottom );
5814 PaintBorderLine(rRect,aVert,this,pCol);
5815 }
5816 }
5817 }
5818 }
5819 else
5820 {
5821 nY -= nRuby;
5822 if( bBorder )
5823 {
5824 SwTwips nPos = std::max( SwTwips(aInter.Left()), nY );
5825 SwTwips nW = std::min(nRight, SwTwips(aTmp.Pos().X())) - nPos;
5826 SwRect aVert( Point( nPos, aGrid.Top() ),
5827 Size( nW, 1 ) );
5828 if( nW > 0 )
5829 {
5830 if( bLeft )
5831 PaintBorderLine(rRect,aVert,this,pCol);
5832 if( bRight )
5833 {
5834 aVert.Pos().setY( nGridBottom );
5835 PaintBorderLine(rRect,aVert,this,pCol);
5836 }
5837 }
5838 }
5839 }
5840 bGrid = !bGrid;
5841 }
5842 }
5843 else
5844 {
5845 SwTwips nOrig = aGrid.Top();
5846 SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
5847 SwRect aTmp( Point( aInter.Left(), nY ),
5848 Size( aInter.Width(), 1 ) );
5849 //for textgrid refactor
5850 SwTwips nX = aGrid.Left() + nGridWidth *
5851 ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
5852 if( nX < aInter.Left() )
5853 nX += nGridWidth;
5854 SwTwips nGridRight = aGrid.Left() + aGrid.Width();
5855 bool bLeft = aGrid.Left() >= aInter.Left();
5856 bool bRight = nGridRight <= nRight;
5857 bool bBorder = bLeft || bRight;
5858 while( nY < aInter.Top() )
5859 {
5860 aTmp.Pos().setY(nY);
5861 if( bGrid )
5862 {
5863 nY += nGrid;
5864 SwTwips nPosY = std::max( aInter.Top(), aTmp.Pos().getY() );
5865 SwTwips nHeight = std::min(nBottom, nY ) - nPosY;
5866 if( nHeight )
5867 {
5868 if( bCell )
5869 {
5870 SwRect aVert( Point( nX, nPosY ),
5871 Size( 1, nHeight ) );
5872 while( aVert.Left() <= nRight )
5873 {
5874 PaintBorderLine(rRect,aVert,this,pCol);
5875 aVert.Pos().AdjustX(nGridWidth ); //for textgrid refactor
5876 }
5877 }
5878 else if ( bBorder )
5879 {
5880 SwRect aVert( Point( aGrid.Left(), nPosY ),
5881 Size( 1, nHeight ) );
5882 if( bLeft )
5883 PaintBorderLine(rRect,aVert,this,pCol);
5884 if( bRight )
5885 {
5886 aVert.Pos().setX( nGridRight );
5887 PaintBorderLine(rRect,aVert,this,pCol);
5888 }
5889 }
5890 }
5891 }
5892 else
5893 {
5894 nY += nRuby;
5895 if( bBorder )
5896 {
5897 SwTwips nPos = std::max(aInter.Top(),aTmp.Pos().getY());
5898 SwTwips nH = std::min( nBottom, nY ) - nPos;
5899 SwRect aVert( Point( aGrid.Left(), nPos ),
5900 Size( 1, nH ) );
5901 if( nH > 0 )
5902 {
5903 if( bLeft )
5904 PaintBorderLine(rRect,aVert,this,pCol);
5905 if( bRight )
5906 {
5907 aVert.Pos().setX(nGridRight);
5908 PaintBorderLine(rRect,aVert,this,pCol);
5909 }
5910 }
5911 }
5912 }
5913 bGrid = !bGrid;
5914 }
5915 while( nY <= nBottom )
5916 {
5917 aTmp.Pos().setY(nY);
5918 PaintBorderLine( rRect, aTmp, this, pCol);
5919 if( bGrid )
5920 {
5921 nY += nGrid;
5922 SwTwips nHeight = std::min(nBottom, nY) - aTmp.Pos().getY();
5923 if( nHeight )
5924 {
5925 if( bCell )
5926 {
5927 SwRect aVert( Point( nX, aTmp.Pos().getY() ),
5928 Size( 1, nHeight ) );
5929 while( aVert.Left() <= nRight )
5930 {
5931 PaintBorderLine( rRect, aVert, this, pCol);
5932 aVert.Pos().setX(aVert.Pos().getX() + nGridWidth); //for textgrid refactor
5933 }
5934 }
5935 else if( bBorder )
5936 {
5937 SwRect aVert( Point( aGrid.Left(),
5938 aTmp.Pos().getY() ), Size( 1, nHeight ) );
5939 if( bLeft )
5940 PaintBorderLine(rRect,aVert,this,pCol);
5941 if( bRight )
5942 {
5943 aVert.Pos().setX(nGridRight);
5944 PaintBorderLine(rRect,aVert,this,pCol);
5945 }
5946 }
5947 }
5948 }
5949 else
5950 {
5951 nY += nRuby;
5952 if( bBorder )
5953 {
5954 SwTwips nPos = std::max(aInter.Top(),aTmp.Pos().Y());
5955 SwTwips nH = std::min( nBottom, nY ) - nPos;
5956 SwRect aVert( Point( aGrid.Left(), nPos ),
5957 Size( 1, nH ) );
5958 if( nH > 0 )
5959 {
5960 if( bLeft )
5961 PaintBorderLine(rRect,aVert,this,pCol);
5962 if( bRight )
5963 {
5964 aVert.Pos().setX(nGridRight);
5965 PaintBorderLine(rRect,aVert,this,pCol);
5966 }
5967 }
5968 }
5969 }
5970 bGrid = !bGrid;
5971 }
5972 }
5973}
5974
5990void SwPageFrame::PaintMarginArea( const SwRect& _rOutputRect,
5991 SwViewShell const * _pViewShell ) const
5992{
5993 if ( !_pViewShell->GetWin() || _pViewShell->GetViewOptions()->getBrowseMode() )
5994 return;
5995
5996 // Simplified paint with DrawingLayer FillStyle
5997 SwRect aPgRect = getFrameArea();
5998 aPgRect.Intersection_( _rOutputRect );
5999
6000 if(!aPgRect.IsEmpty())
6001 {
6002 OutputDevice *pOut = _pViewShell->GetOut();
6003
6004 if(pOut->GetFillColor() != aGlobalRetoucheColor)
6005 {
6006 pOut->SetFillColor(aGlobalRetoucheColor);
6007 }
6008
6009 pOut->DrawRect(aPgRect.SVRect());
6010 }
6011}
6012
6014
6016{
6017 const SwViewShell *pSh = getRootFrame()->GetCurrShell();
6018 const bool bIsLTR = getRootFrame()->IsLeftToRightViewLayout();
6019
6020 // We paint the right shadow if we're not in book mode
6021 // or if we've no sibling or are the last page of the "row"
6022 return !pSh || (!pSh->GetViewOptions()->IsViewLayoutBookMode()) || !GetNext()
6023 || (this == Lower()) || (bIsLTR && OnRightPage())
6024 || (!bIsLTR && !OnRightPage());
6025
6026}
6027
6029{
6030 const SwViewShell *pSh = getRootFrame()->GetCurrShell();
6031 const bool bIsLTR = getRootFrame()->IsLeftToRightViewLayout();
6032
6033 // We paint the left shadow if we're not in book mode
6034 // or if we've no sibling or are the last page of the "row"
6035 return !pSh || (!pSh->GetViewOptions()->IsViewLayoutBookMode()) || !GetPrev()
6036 || (bIsLTR && !OnRightPage())
6037 || (!bIsLTR && OnRightPage());
6038}
6039
6044/*static*/ void SwPageFrame::GetHorizontalShadowRect( const SwRect& _rPageRect,
6045 const SwViewShell* _pViewShell,
6046 OutputDevice const * pRenderContext,
6047 SwRect& _orHorizontalShadowRect,
6048 bool bPaintLeftShadow,
6049 bool bPaintRightShadow,
6050 bool bRightSidebar )
6051{
6052 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
6053 SwRect aAlignedPageRect( _rPageRect );
6054 ::SwAlignRect( aAlignedPageRect, _pViewShell, pRenderContext );
6055 SwRect aPagePxRect(pRenderContext->LogicToPixel( aAlignedPageRect.SVRect() ));
6056
6057 tools::Long lShadowAdjustment = snShadowPxWidth - 1; // TODO: extract this
6058
6059 _orHorizontalShadowRect.Chg(
6060 Point( aPagePxRect.Left() + (bPaintLeftShadow ? lShadowAdjustment : 0), 0 ),
6061 Size( aPagePxRect.Width() - ( (bPaintLeftShadow ? lShadowAdjustment : 0) + (bPaintRightShadow ? lShadowAdjustment : 0) ),
6062 snShadowPxWidth ) );
6063
6064 if(pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
6065 {
6066 // Notes are displayed, we've to extend borders
6067 SwTwips aSidebarTotalWidth = pMgr->GetSidebarWidth(true) + pMgr->GetSidebarBorderWidth(true);
6068 if(bRightSidebar)
6069 _orHorizontalShadowRect.AddRight( aSidebarTotalWidth );
6070 else
6071 _orHorizontalShadowRect.AddLeft( - aSidebarTotalWidth );
6072 }
6073}
6074
6075namespace {
6076
6077enum PaintArea {LEFT, RIGHT, TOP, BOTTOM};
6078
6079}
6080
6081#define BORDER_TILE_SIZE 512
6082
6084static void lcl_paintBitmapExToRect(vcl::RenderContext *pOut, const Point& aPoint, const Size& aSize, const BitmapEx& rBitmapEx, PaintArea eArea)
6085{
6087 {
6088 // The problem is that if we get called multiple times and the color is
6089 // partly transparent, then the result will get darker and darker. To avoid
6090 // this, always paint the background color before doing the real paint.
6091 tools::Rectangle aRect(aPoint, aSize);
6092
6093 if (!aRect.IsEmpty())
6094 {
6095 switch (eArea)
6096 {
6097 case LEFT: aRect.SetLeft( aRect.Right() - 1 ); break;
6098 case RIGHT: aRect.SetRight( aRect.Left() + 1 ); break;
6099 case TOP: aRect.SetTop( aRect.Bottom() - 1 ); break;
6100 case BOTTOM: aRect.SetBottom( aRect.Top() + 1 ); break;
6101 }
6102 }
6103
6104 pOut->SetFillColor(SwViewOption::GetCurrentViewOptions().GetAppBackgroundColor());
6105 pOut->SetLineColor();
6106 pOut->DrawRect(pOut->PixelToLogic(aRect));
6107 }
6108
6109 // Tiled render if necessary
6110 tools::Rectangle aComplete(aPoint, aSize);
6112
6113 tools::Long iterX = eArea != RIGHT && eArea != LEFT ? BORDER_TILE_SIZE : 0;
6114 tools::Long iterY = eArea == RIGHT || eArea == LEFT ? BORDER_TILE_SIZE : 0;
6115
6116 for (tools::Rectangle aTile(aPoint, aTileSize); true; aTile.Move(iterX, iterY))
6117 {
6118 tools::Rectangle aRender = aComplete.GetIntersection(aTile);
6119 if (aRender.IsEmpty())
6120 break;
6121 pOut->DrawBitmapEx(pOut->PixelToLogic(aRender.TopLeft()),
6122 pOut->PixelToLogic(aRender.GetSize()),
6123 Point(0, 0), aRender.GetSize(),
6124 rBitmapEx);
6125 }
6126
6127}
6128
6135/*static*/ void SwPageFrame::PaintBorderAndShadow( const SwRect& _rPageRect,
6136 const SwViewShell* _pViewShell,
6137 bool bPaintLeftShadow,
6138 bool bPaintRightShadow,
6139 bool bRightSidebar )
6140{
6141 // No shadow in prefs
6142 if (!_pViewShell->GetViewOptions()->IsShadow())
6143 return;
6144
6145 // #i16816# tagged pdf support
6146 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *_pViewShell->GetOut() );
6147
6149 vcl::bitmap::loadFromName(BMP_PAGE_SHADOW_MASK,
6150 ImageLoadFlags::IgnoreDarkTheme | ImageLoadFlags::IgnoreScalingFactor));
6151
6152 drawinglayer::primitive2d::DiscreteShadow& shadowMask = *shadowMaskObj.get();
6153 static vcl::DeleteOnDeinit< BitmapEx > aPageTopRightShadowObj {};
6154 static vcl::DeleteOnDeinit< BitmapEx > aPageBottomRightShadowObj {};
6155 static vcl::DeleteOnDeinit< BitmapEx > aPageBottomLeftShadowObj {};
6156 static vcl::DeleteOnDeinit< BitmapEx > aPageBottomShadowBaseObj {};
6157 static vcl::DeleteOnDeinit< BitmapEx > aPageRightShadowBaseObj {};
6158 static vcl::DeleteOnDeinit< BitmapEx > aPageTopShadowBaseObj {};
6159 static vcl::DeleteOnDeinit< BitmapEx > aPageTopLeftShadowObj {};
6160 static vcl::DeleteOnDeinit< BitmapEx > aPageLeftShadowBaseObj {};
6161 BitmapEx& aPageTopRightShadow = *aPageTopRightShadowObj.get();
6162 BitmapEx& aPageBottomRightShadow = *aPageBottomRightShadowObj.get();
6163 BitmapEx& aPageBottomLeftShadow = *aPageBottomLeftShadowObj.get();
6164 BitmapEx& aPageBottomShadow = *aPageBottomShadowBaseObj.get();
6165 BitmapEx& aPageRightShadow = *aPageRightShadowBaseObj.get();
6166 BitmapEx& aPageTopShadow = *aPageTopShadowBaseObj.get();
6167 BitmapEx& aPageTopLeftShadow = *aPageTopLeftShadowObj.get();
6168 BitmapEx& aPageLeftShadow = *aPageLeftShadowBaseObj.get();
6169 static Color aShadowColor( COL_AUTO );
6170
6171 SwRect aAlignedPageRect( _rPageRect );
6172 ::SwAlignRect( aAlignedPageRect, _pViewShell, _pViewShell->GetOut() );
6173 SwRect aPagePxRect(_pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() ));
6174
6175 if (aShadowColor != _pViewShell->GetViewOptions()->GetShadowColor())
6176 {
6177 aShadowColor = _pViewShell->GetViewOptions()->GetShadowColor();
6178
6179 AlphaMask aMask( shadowMask.getBottomRight().GetBitmap() );
6180 Bitmap aFilledSquare(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6181 aFilledSquare.Erase( aShadowColor );
6182 aPageBottomRightShadow = BitmapEx( aFilledSquare, aMask );
6183
6184 aMask = AlphaMask( shadowMask.getBottomLeft().GetBitmap() );
6185 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6186 aFilledSquare.Erase( aShadowColor );
6187 aPageBottomLeftShadow = BitmapEx( aFilledSquare, aMask );
6188
6189 aMask = AlphaMask( shadowMask.getBottom().GetBitmap() );
6190 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6191 aFilledSquare.Erase( aShadowColor );
6192 aPageBottomShadow = BitmapEx( aFilledSquare, aMask );
6193
6194 aMask = AlphaMask( shadowMask.getTop().GetBitmap() );
6195 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6196 aFilledSquare.Erase( aShadowColor );
6197 aPageTopShadow = BitmapEx( aFilledSquare, aMask );
6198
6199 aMask = AlphaMask( shadowMask.getTopRight().GetBitmap() );
6200 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6201 aFilledSquare.Erase( aShadowColor );
6202 aPageTopRightShadow = BitmapEx( aFilledSquare, aMask );
6203
6204 aMask = AlphaMask( shadowMask.getRight().GetBitmap() );
6205 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6206 aFilledSquare.Erase( aShadowColor );
6207 aPageRightShadow = BitmapEx( aFilledSquare, aMask );
6208
6209 aMask = AlphaMask( shadowMask.getTopLeft().GetBitmap() );
6210 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6211 aFilledSquare.Erase( aShadowColor );
6212 aPageTopLeftShadow = BitmapEx( aFilledSquare, aMask );
6213
6214 aMask = AlphaMask( shadowMask.getLeft().GetBitmap() );
6215 aFilledSquare = Bitmap(aMask.GetSizePixel(), vcl::PixelFormat::N24_BPP);
6216 aFilledSquare.Erase( aShadowColor );
6217 aPageLeftShadow = BitmapEx( aFilledSquare, aMask );
6218 }
6219
6220 SwRect aPaintRect;
6221 OutputDevice *pOut = _pViewShell->GetOut();
6222
6223 SwPageFrame::GetHorizontalShadowRect( _rPageRect, _pViewShell, pOut, aPaintRect, bPaintLeftShadow, bPaintRightShadow, bRightSidebar );
6224
6225 // Right shadow & corners
6226 if ( bPaintRightShadow )
6227 {
6228 pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Right(), aPagePxRect.Bottom() + 1 - (aPageBottomRightShadow.GetSizePixel().Height() - snShadowPxWidth) ) ),
6229 aPageBottomRightShadow );
6230 pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Right(), aPagePxRect.Top() - snShadowPxWidth ) ),
6231 aPageTopRightShadow );
6232
6233 if (aPagePxRect.Height() > 2 * snShadowPxWidth)
6234 {
6235 const tools::Long nWidth = aPageRightShadow.GetSizePixel().Width();
6236 const tools::Long nHeight = aPagePxRect.Height() - 2 * (snShadowPxWidth - 1);
6237 if (aPageRightShadow.GetSizePixel().Height() < BORDER_TILE_SIZE)
6238 aPageRightShadow.Scale(Size(nWidth, BORDER_TILE_SIZE), BmpScaleFlag::Fast);
6239
6241 Point(aPaintRect.Right() + snShadowPxWidth, aPagePxRect.Top() + snShadowPxWidth - 1),
6242 Size(nWidth, nHeight),
6243 aPageRightShadow, RIGHT);
6244 }
6245 }
6246
6247 // Left shadows and corners
6248 if(bPaintLeftShadow)
6249 {
6250 const tools::Long lLeft = aPaintRect.Left() - aPageBottomLeftShadow.GetSizePixel().Width();
6251 pOut->DrawBitmapEx( pOut->PixelToLogic( Point( lLeft,
6252 aPagePxRect.Bottom() + 1 + snShadowPxWidth - aPageBottomLeftShadow.GetSizePixel().Height() ) ), aPageBottomLeftShadow );
6253 pOut->DrawBitmapEx( pOut->PixelToLogic( Point( lLeft, aPagePxRect.Top() - snShadowPxWidth ) ), aPageTopLeftShadow );
6254 if (aPagePxRect.Height() > 2 * snShadowPxWidth)
6255 {
6256 const tools::Long nWidth = aPageLeftShadow.GetSizePixel().Width();
6257 const tools::Long nHeight = aPagePxRect.Height() - 2 * (snShadowPxWidth - 1);
6258 if (aPageLeftShadow.GetSizePixel().Height() < BORDER_TILE_SIZE)
6259 aPageLeftShadow.Scale(Size(nWidth, BORDER_TILE_SIZE), BmpScaleFlag::Fast);
6260
6262 Point(lLeft, aPagePxRect.Top() + snShadowPxWidth - 1),
6263 Size(nWidth, nHeight),
6264 aPageLeftShadow, LEFT);
6265 }
6266 }
6267
6268 // Bottom shadow
6269 const tools::Long nBottomHeight = aPageBottomShadow.GetSizePixel().Height();
6270 if (aPageBottomShadow.GetSizePixel().Width() < BORDER_TILE_SIZE)
6271 aPageBottomShadow.Scale(Size(BORDER_TILE_SIZE, nBottomHeight), BmpScaleFlag::Fast);
6272
6274 Point(aPaintRect.Left(), aPagePxRect.Bottom() + 2),
6275 Size(aPaintRect.Width(), nBottomHeight),
6276 aPageBottomShadow, BOTTOM);
6277
6278 // Top shadow
6279 const tools::Long nTopHeight = aPageTopShadow.GetSizePixel().Height();
6280 if (aPageTopShadow.GetSizePixel().Width() < BORDER_TILE_SIZE)
6281 aPageTopShadow.Scale(Size(BORDER_TILE_SIZE, nTopHeight), BmpScaleFlag::Fast);
6282
6284 Point(aPaintRect.Left(), aPagePxRect.Top() - snShadowPxWidth),
6285 Size(aPaintRect.Width(), nTopHeight),
6286 aPageTopShadow, TOP);
6287}
6288
6293/*static*/void SwPageFrame::PaintNotesSidebar(const SwRect& _rPageRect, SwViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
6294{
6295 //TODO: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
6296 if (!_pViewShell )
6297 return;
6298
6299 SwRect aPageRect( _rPageRect );
6300 SwAlignRect( aPageRect, _pViewShell, _pViewShell->GetOut() );
6301
6302 const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
6303 if (!(pMgr && pMgr->ShowNotes() && pMgr->HasNotes())) // do not show anything in print preview
6304 return;
6305
6306 sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
6307 const tools::Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
6308 //draw border and sidepane
6309 _pViewShell->GetOut()->SetLineColor();
6310 if (!bRight)
6311 {
6312 _pViewShell->GetOut()->SetFillColor(_pViewShell->GetViewOptions()->GetObjectBoundariesColor());
6313 _pViewShell->GetOut()->DrawRect(tools::Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ;
6314 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6315 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6316 else
6317 _pViewShell->GetOut()->SetFillColor(_pViewShell->GetViewOptions()->GetSectionBoundColor());
6318 _pViewShell->GetOut()->DrawRect(tools::Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ;
6319 }
6320 else
6321 {
6322 _pViewShell->GetOut()->SetFillColor(_pViewShell->GetViewOptions()->GetObjectBoundariesColor());
6323 SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
6324 _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
6325 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6326 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6327 else
6328 _pViewShell->GetOut()->SetFillColor(_pViewShell->GetViewOptions()->GetSectionBoundColor());
6329 SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
6330 _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
6331 }
6332 if (!pMgr->ShowScrollbar(nPageNum))
6333 return;
6334
6335 // draw scrollbar area and arrows
6336 Point aPointBottom;
6337 Point aPointTop;
6338 aPointBottom = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() - pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()) :
6339 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
6340 aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
6341 Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
6342 Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
6343 tools::Rectangle aRectBottom(aPointBottom,aSize);
6344 tools::Rectangle aRectTop(aPointTop,aSize);
6345
6346 if (aRectBottom.Overlaps(aVisRect))
6347 {
6348
6349 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6350 {
6351 _pViewShell->GetOut()->SetLineColor(COL_WHITE);
6352 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6353 }
6354 else
6355 {
6356 _pViewShell->GetOut()->SetLineColor(COL_BLACK);
6357 _pViewShell->GetOut()->SetFillColor(COL_LIGHTGRAY);
6358 }
6359 _pViewShell->GetOut()->DrawRect(aRectBottom);
6360 _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
6361
6362 _pViewShell->GetOut()->SetLineColor();
6363 Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6364 Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6365 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
6366 }
6367 if (!aRectTop.Overlaps(aVisRect))
6368 return;
6369
6370 if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
6371 {
6372 _pViewShell->GetOut()->SetLineColor(COL_WHITE);
6373 _pViewShell->GetOut()->SetFillColor(COL_BLACK);
6374 }
6375 else
6376 {
6377 _pViewShell->GetOut()->SetLineColor(COL_BLACK);
6378 _pViewShell->GetOut()->SetFillColor(COL_LIGHTGRAY);
6379 }
6380 _pViewShell->GetOut()->DrawRect(aRectTop);
6381 _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
6382
6383 _pViewShell->GetOut()->SetLineColor();
6384 Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6385 Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
6386 PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
6387}
6388
6389/*static*/ void SwPageFrame::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, SwViewShell const * _pViewShell, const Color& rColorUp, const Color& rColorDown)
6390{
6391 tools::Polygon aTriangleUp(3);
6392 tools::Polygon aTriangleDown(3);
6393
6394 aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
6395 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
6396 aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
6397
6398 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
6399 aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
6400 aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
6401
6402 _pViewShell->GetOut()->SetFillColor(rColorUp);
6403 _pViewShell->GetOut()->DrawPolygon(aTriangleUp);
6404 _pViewShell->GetOut()->SetFillColor(rColorDown);
6405 _pViewShell->GetOut()->DrawPolygon(aTriangleDown);
6406}
6407
6413/*static*/ void SwPageFrame::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
6414 const SwViewShell* _pViewShell,
6415 OutputDevice const * pRenderContext,
6416 SwRect& _orBorderAndShadowBoundRect,
6417 bool bLeftShadow,
6418 bool bRightShadow,
6419 bool bRightSidebar
6420 )
6421{
6422 SwRect aAlignedPageRect( _rPageRect );
6423 ::SwAlignRect( aAlignedPageRect, _pViewShell, pRenderContext );
6424 SwRect aPagePxRect(pRenderContext->LogicToPixel( aAlignedPageRect.SVRect() ));
6425 aPagePxRect.AddBottom( snShadowPxWidth + 1 );
6426 aPagePxRect.AddTop( - snShadowPxWidth - 1 );
6427
6428 SwRect aTmpRect;
6429
6430 // Always ask for full shadow since we want a bounding rect
6431 // including at least the page frame
6432 SwPageFrame::GetHorizontalShadowRect( _rPageRect, _pViewShell, pRenderContext, aTmpRect, false, false, bRightSidebar );
6433
6434 if(bLeftShadow) aPagePxRect.Left( aTmpRect.Left() - snShadowPxWidth - 1);
6435 if(bRightShadow) aPagePxRect.Right( aTmpRect.Right() + snShadowPxWidth + 1);
6436
6437 _orBorderAndShadowBoundRect = SwRect(pRenderContext->PixelToLogic( aPagePxRect.SVRect() ));
6438}
6439
6441{
6442 const SwViewShell *pSh = getRootFrame()->GetCurrShell();
6443 SwRect aPageRect( getFrameArea() );
6444 SwRect aResult;
6445
6446 if(!pSh) {
6447 return SwRect( Point(0, 0), Size(0, 0) );
6448 }
6449
6450 SwPageFrame::GetBorderAndShadowBoundRect( aPageRect, pSh, pOutputDevice, aResult,
6452 return aResult;
6453}
6454
6456{
6457 const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : nullptr;
6458 const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
6459 return nRet;
6460}
6461
6462void SwFrame::PaintBaBo( const SwRect& rRect, const SwPageFrame *pPage,
6463 const bool bOnlyTextBackground ) const
6464{
6465 if ( !pPage )
6466 pPage = FindPageFrame();
6467
6468 OutputDevice *pOut = gProp.pSGlobalShell->GetOut();
6469
6470 // #i16816# tagged pdf support
6471 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pOut );
6472
6474 pOut->SetLineColor();
6475
6476 SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
6477 const SwBorderAttrs &rAttrs = *aAccess.Get();
6478
6479 // take care of page margin area
6480 // Note: code move from <SwFrame::PaintSwFrameBackground(..)> to new method
6481 // <SwPageFrame::Paintmargin(..)>.
6482 if ( IsPageFrame() && !bOnlyTextBackground)
6483 {
6484 static_cast<const SwPageFrame*>(this)->PaintMarginArea( rRect, gProp.pSGlobalShell );
6485 }
6486
6487 // paint background
6488 {
6489 PaintSwFrameBackground( rRect, pPage, rAttrs, false, true/*bLowerBorder*/, bOnlyTextBackground );
6490 }
6491
6492 // paint border before painting background
6493 // paint grid for page frame and paint border
6494 if (!bOnlyTextBackground)
6495 {
6496 SwRect aRect( rRect );
6497
6498 if( IsPageFrame() )
6499 {
6500 static_cast<const SwPageFrame*>(this)->PaintGrid( pOut, aRect );
6501 }
6502
6503 PaintSwFrameShadowAndBorder(aRect, pPage, rAttrs);
6504 }
6505
6506 pOut->Pop();
6507}
6508
6510{
6511 if (pA == pB)
6512 return true;
6513 if (!pA || !pB)
6514 return false;
6515 return pA->getFillAttribute() == pB->getFillAttribute();
6516}
6517
6520void SwFrame::PaintSwFrameBackground( const SwRect &rRect, const SwPageFrame *pPage,
6521 const SwBorderAttrs & rAttrs,
6522 const bool bLowerMode,
6523 const bool bLowerBorder,
6524 const bool bOnlyTextBackground ) const
6525{
6526 // #i1837# - no paint of table background, if corresponding option is *not* set.
6527 SwViewShell *pSh = gProp.pSGlobalShell;
6528 if( IsTabFrame() &&
6529 !pSh->GetViewOptions()->IsTable() )
6530 {
6531 return;
6532 }
6533
6534 // nothing to do for covered table cells:
6535 if( IsCellFrame() && IsCoveredCell() )
6536 return;
6537
6538 // #i16816# tagged pdf support
6539 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pSh->GetOut() );
6540
6541 const SvxBrushItem* pItem;
6542 // temporary background brush for a fly frame without a background brush
6543 std::unique_ptr<SvxBrushItem> pTmpBackBrush;
6544 std::optional<Color> pCol;
6545 SwRect aOrigBackRect;
6546 const bool bPageFrame = IsPageFrame();
6547 bool bLowMode = true;
6549
6550 bool bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, bLowerMode, /*bConsiderTextBox=*/false );
6551
6552 // show track changes of table row
6553 if( IsRowFrame() && !getRootFrame()->IsHideRedlines() )
6554 {
6555 RedlineType eType = static_cast<const SwRowFrame*>(this)->GetTabLine()->GetRedlineType();
6556 if ( RedlineType::Delete == eType || RedlineType::Insert == eType )
6557 {
6558 pCol = RedlineType::Delete == eType ? COL_AUTHOR_TABLE_DEL : COL_AUTHOR_TABLE_INS;
6559 bBack = true;
6560 }
6561 }
6562 else if ( IsCellFrame() && !getRootFrame()->IsHideRedlines() )
6563 {
6564 RedlineType eType = static_cast<const SwCellFrame*>(this)->GetTabBox()->GetRedlineType();
6565 if ( RedlineType::Delete == eType || RedlineType::Insert == eType )
6566 {
6567 pCol = RedlineType::Delete == eType ? COL_AUTHOR_TABLE_DEL : COL_AUTHOR_TABLE_INS;
6568 bBack = true;
6569 }
6570 }
6571
6572 if ( bBack && IsCellFrame() && !getRootFrame()->IsHideRedlines() &&
6573 // skip cell background to show the row colored according to its tracked change
6574 RedlineType::None != static_cast<const SwRowFrame*>(GetUpper())->GetTabLine()->GetRedlineType() )
6575 {
6576 return;
6577 }
6578
6579 //- Output if a separate background is used.
6580 bool bNoFlyBackground = !gProp.bSFlyMetafile && !bBack && IsFlyFrame();
6581 if ( bNoFlyBackground )
6582 {
6583 // Fly frame has no background.
6584 // Try to find background brush at parents, if previous call of
6585 // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
6586 if ( bLowerMode )
6587 {
6588 bBack = GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigBackRect, false, /*bConsiderTextBox=*/false );
6589 }
6590 // If still no background found for the fly frame, initialize the
6591 // background brush <pItem> with global retouche color and set <bBack>
6592 // to true, that fly frame will paint its background using this color.
6593 if ( !bBack )
6594 {
6595 // #i6467# - on print output, pdf output and in embedded mode not editing color COL_WHITE is used
6596 // instead of the global retouche color.
6597 if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
6598 pSh->GetViewOptions()->IsPDFExport() ||
6599 ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED &&
6600 !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
6601 )
6602 )
6603 {
6604 pTmpBackBrush.reset(new SvxBrushItem( COL_WHITE, RES_BACKGROUND ));
6605
6606 //UUU
6607 aFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(COL_WHITE);
6608 }
6609 else
6610 {
6611 pTmpBackBrush.reset(new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND));
6612
6613 //UUU
6614 aFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aGlobalRetoucheColor);
6615 }
6616
6617 pItem = pTmpBackBrush.get();
6618 bBack = true;
6619 }
6620 }
6621
6622 SwRect aPaintRect( getFrameArea() );
6623 if( IsTextFrame() || IsSctFrame() )
6624 aPaintRect = UnionFrame( true );
6625
6626 // bOnlyTextBackground means background that's on top of background shapes,
6627 // this includes both text and cell frames.
6628 if ( (!bOnlyTextBackground || IsTextFrame() || IsCellFrame()) && aPaintRect.Overlaps( rRect ) )
6629 {
6630 if ( bBack || bPageFrame || !bLowerMode )
6631 {
6632 const bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
6633 SwRect aRect;
6634 if ( (bPageFrame && bBrowse) ||
6636 {
6637 aRect = getFrameArea();
6638 ::SwAlignRect( aRect, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
6639 }
6640 else
6641 {
6642 if (bPageFrame && GetAttrSet()->GetItem<SfxBoolItem>(RES_BACKGROUND_FULL_SIZE)->GetValue())
6643 {
6644 aRect = getFrameArea();
6645 ::SwAlignRect(aRect, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut());
6646 }
6647 else
6648 {
6649 ::lcl_CalcBorderRect( aRect, this, rAttrs, false, gProp);
6650 }
6651
6652 if ( (IsTextFrame() || IsTabFrame()) && GetPrev() )
6653 {
6654 if ( GetPrev()->GetAttrSet()->GetBackground() == GetAttrSet()->GetBackground() &&
6656 {
6657 aRect.Top( getFrameArea().Top() );
6658 }
6659 }
6660 }
6661 aRect.Intersection( rRect );
6662
6663 OutputDevice *pOut = pSh->GetOut();
6664
6665 if ( aRect.HasArea() )
6666 {
6667 std::unique_ptr<SvxBrushItem> pNewItem;
6668
6669 if( pCol )
6670 {
6671 pNewItem.reset(new SvxBrushItem( *pCol, RES_BACKGROUND ));
6672 pItem = pNewItem.get();
6673 aFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(*pCol);
6674 }
6675
6676 SwRegionRects aRegion( aRect );
6679 if (pPage->GetSortedObjs() &&
6681 {
6682 ::lcl_SubtractFlys( this, pPage, aRect, aRegion, aClipState, gProp );
6683 }
6684
6685 // Determine, if background transparency
6686 // have to be considered for drawing.
6687 // Status Quo: background transparency have to be
6688 // considered for fly frames
6689 const bool bConsiderBackgroundTransparency = IsFlyFrame();
6690 bool bDone(false);
6691
6692 // #i125189# We are also done when the new DrawingLayer FillAttributes are used
6693 // or the FillStyle is set (different from drawing::FillStyle_NONE)
6694 if (aFillAttributes)
6695 {
6696 if(aFillAttributes->isUsed())
6697 {
6698 // check if really something is painted
6699 bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRegion, aClipState, *pOut);
6700 }
6701
6702 if(!bDone)
6703 {
6704 // if not, still a FillStyle could be set but the transparency is at 100%,
6705 // thus need to check the model data itself for FillStyle (do not rely on
6706 // SdrAllFillAttributesHelper since it already contains optimized information,
6707 // e.g. transparency leads to no fill)
6708 const drawing::FillStyle eFillStyle(GetAttrSet()->Get(XATTR_FILLSTYLE).GetValue());
6709
6710 if(drawing::FillStyle_NONE != eFillStyle)
6711 {
6712 bDone = true;
6713 }
6714 }
6715 }
6716
6717 if(!bDone)
6718 {
6719 for (size_t i = 0; i < aRegion.size(); ++i)
6720 {
6721 if (1 < aRegion.size())
6722 {
6723 ::SwAlignRect( aRegion[i], gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
6724 if( !aRegion[i].HasArea() )
6725 continue;
6726 }
6727 // add 6th parameter to indicate, if background transparency have to be considered
6728 // Set missing 5th parameter to the default value GRFNUM_NO
6729 // - see declaration in /core/inc/frmtool.hxx.
6731 pItem,
6732 *pOut,
6733 aOrigBackRect,
6734 aRegion[i],
6735 GRFNUM_NO,
6736 bConsiderBackgroundTransparency );
6737 }
6738 }
6739 }
6740 }
6741 else
6742 bLowMode = bLowerMode;
6743 }
6744
6745 // delete temporary background brush.
6746 pTmpBackBrush.reset();
6747
6748 //Now process lower and his neighbour.
6749 //We end this as soon as a Frame leaves the chain and therefore is not a lower
6750 //of me anymore
6751 const SwFrame *pFrame = GetLower();
6752 if ( !pFrame )
6753 return;
6754
6755 SwRect aFrameRect;
6756 SwRect aRect( GetPaintArea() );
6757 aRect.Intersection_( rRect );
6758 SwRect aBorderRect( aRect );
6759 SwShortCut aShortCut( *pFrame, aBorderRect );
6760 do
6761 { if ( gProp.pSProgress )
6763
6764 aFrameRect = pFrame->GetPaintArea();
6765 if ( aFrameRect.Overlaps( aBorderRect ) )
6766 {
6767 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFrame );
6768 const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
6769 if ( ( pFrame->IsLayoutFrame() && bLowerBorder ) || aFrameRect.Overlaps( aRect ) )
6770 {
6771 pFrame->PaintSwFrameBackground( aRect, pPage, rTmpAttrs, bLowMode,
6772 bLowerBorder, bOnlyTextBackground );
6773 }
6774
6775 if ( bLowerBorder )
6776 {
6777 pFrame->PaintSwFrameShadowAndBorder( aBorderRect, pPage, rTmpAttrs );
6778 }
6779 }
6780 pFrame = pFrame->GetNext();
6781 } while ( pFrame && pFrame->GetUpper() == this &&
6782 !aShortCut.Stop( aFrameRect ) );
6783}
6784
6786void SwPageFrame::RefreshSubsidiary( const SwRect &rRect ) const
6787{
6788 if ( !(isSubsidiaryLinesEnabled() || isTableBoundariesEnabled()
6790 return;
6791
6792 if ( !rRect.HasArea() )
6793 return;
6794
6795 //During paint using the root, the array is controlled from there.
6796 //Otherwise we'll handle it for our self.
6797 bool bDelSubs = false;
6798 if ( !gProp.pSSubsLines )
6799 {
6800 gProp.pSSubsLines.reset(new SwSubsRects);
6801 // create container for special subsidiary lines
6802 gProp.pSSpecSubsLines.reset(new SwSubsRects);
6803 bDelSubs = true;
6804 }
6805
6806 RefreshLaySubsidiary( this, rRect );
6807
6808 if ( bDelSubs )
6809 {
6810 // paint special subsidiary lines and delete its container
6811 gProp.pSSpecSubsLines->PaintSubsidiary( gProp.pSGlobalShell->GetOut(), nullptr, gProp );
6812 gProp.pSSpecSubsLines.reset();
6813
6814 gProp.pSSubsLines->PaintSubsidiary(gProp.pSGlobalShell->GetOut(), gProp.pSLines.get(), gProp);
6815 gProp.pSSubsLines.reset();
6816 }
6817}
6818
6820 const SwRect &rRect ) const
6821{
6823 if ( bSubsOpt )
6824 PaintSubsidiaryLines( pPage, rRect );
6825
6826 const SwFrame *pLow = Lower();
6827 if( !pLow )
6828 return;
6829 SwShortCut aShortCut( *pLow, rRect );
6830 while( pLow && !aShortCut.Stop( pLow->getFrameArea() ) )
6831 {
6832 if ( pLow->getFrameArea().Overlaps( rRect ) && pLow->getFrameArea().HasArea() )
6833 {
6834 if ( pLow->IsLayoutFrame() )
6835 static_cast<const SwLayoutFrame*>(pLow)->RefreshLaySubsidiary( pPage, rRect);
6836 else if ( pLow->GetDrawObjs() )
6837 {
6838 const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
6839 for (SwAnchoredObject* pAnchoredObj : rObjs)
6840 {
6842 pAnchoredObj->GetDrawObj()->GetLayer() ) )
6843 if (auto pFly = pAnchoredObj->DynCastFlyFrame() )
6844 {
6845 if ( pFly->IsFlyInContentFrame() && pFly->getFrameArea().Overlaps( rRect ) )
6846 {
6847 if ( !pFly->Lower() || !pFly->Lower()->IsNoTextFrame() ||
6848 !static_cast<const SwNoTextFrame*>(pFly->Lower())->HasAnimation())
6849 pFly->RefreshLaySubsidiary( pPage, rRect );
6850 }
6851 }
6852 }
6853 }
6854 }
6855 pLow = pLow->GetNext();
6856 }
6857}
6858
6864static void lcl_RefreshLine( const SwLayoutFrame *pLay,
6865 const SwPageFrame *pPage,
6866 const Point &rP1,
6867 const Point &rP2,
6868 const SubColFlags nSubColor,
6869 SwLineRects* pSubsLines )
6870{
6871 //In which direction do we loop? Can only be horizontal or vertical.
6872 OSL_ENSURE( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
6873 "Sloped subsidiary lines are not allowed." );
6874
6875 const bool bHori = rP1.Y() == rP2.Y();
6876
6877 // use pointers to member function in order to unify flow
6878 typedef tools::Long (Point::*pmfPtGet)() const;
6879 typedef void (Point::*pmfPtSet)(tools::Long);
6880 const pmfPtGet pDirPtX = &Point::X;
6881 const pmfPtGet pDirPtY = &Point::Y;
6882 const pmfPtGet pDirPt = bHori ? pDirPtX : pDirPtY;
6883 const pmfPtSet pDirPtSetX = &Point::setX;
6884 const pmfPtSet pDirPtSetY = &Point::setY;
6885 const pmfPtSet pDirPtSet = bHori ? pDirPtSetX : pDirPtSetY;
6886
6887 Point aP1( rP1 );
6888 Point aP2( rP2 );
6889
6890 while ( (aP1.*pDirPt)() < (aP2.*pDirPt)() )
6891 {
6892 //If the starting point lies in a fly, it is directly set behind the
6893 //fly.
6894 //The end point moves to the start if the end point lies in a fly or we
6895 //have a fly between starting point and end point.
6896 // In this way, every position is output one by one.
6897
6898 //If I'm a fly I'll only avoid those flys which are places 'above' me;
6899 //this means those who are behind me in the array.
6900 //Even if I'm inside a fly or inside a fly inside a fly a.s.o I won't
6901 //avoid any of those flys.
6902 SwOrderIter aIter( pPage );
6903 const SwFlyFrame *pMyFly = pLay->FindFlyFrame();
6904 if ( pMyFly )
6905 {
6906 aIter.Current( pMyFly->GetVirtDrawObj() );
6907 while ( nullptr != (pMyFly = pMyFly->GetAnchorFrame()->FindFlyFrame()) )
6908 {
6909 if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
6910 aIter.Current( pMyFly->GetVirtDrawObj() );
6911 }
6912 }
6913 else
6914 aIter.Bottom();
6915
6916 while ( aIter() )
6917 {
6918 const SwVirtFlyDrawObj *pObj = static_cast<const SwVirtFlyDrawObj*>(aIter());
6919 const SwFlyFrame *pFly = pObj ? pObj->GetFlyFrame() : nullptr;
6920
6921 //I certainly won't avoid myself, even if I'm placed _inside_ the
6922 //fly I won't avoid it.
6923 if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
6924 {
6925 aIter.Next();
6926 continue;
6927 }
6928
6929 // do *not* consider fly frames with a transparent background.
6930 // do *not* consider fly frame, which belongs to an invisible layer
6931 if ( pFly->IsBackgroundTransparent() ||
6933 {
6934 aIter.Next();
6935 continue;
6936 }
6937
6938 //Is the Obj placed on the line
6939 const tools::Long nP1OthPt = !bHori ? rP1.X() : rP1.Y();
6940 const tools::Rectangle &rBound = pObj->GetCurrentBoundRect();
6941 const Point aDrPt( rBound.TopLeft() );
6942 const tools::Long nDrOthPt = !bHori ? aDrPt.X() : aDrPt.Y();
6943 const Size aDrSz( rBound.GetSize() );
6944 const tools::Long nDrOthSz = !bHori ? aDrSz.Width() : aDrSz.Height();
6945
6946 if ( nP1OthPt >= nDrOthPt && nP1OthPt <= nDrOthPt + nDrOthSz )
6947 {
6948 const tools::Long nDrDirPt = bHori ? aDrPt.X() : aDrPt.Y();
6949 const tools::Long nDrDirSz = bHori ? aDrSz.Width() : aDrSz.Height();
6950
6951 if ( (aP1.*pDirPt)() >= nDrDirPt && (aP1.*pDirPt)() <= nDrDirPt + nDrDirSz )
6952 (aP1.*pDirPtSet)( nDrDirPt + nDrDirSz );
6953
6954 if ( (aP2.*pDirPt)() >= nDrDirPt && (aP1.*pDirPt)() < (nDrDirPt - 1) )
6955 (aP2.*pDirPtSet)( nDrDirPt - 1 );
6956 }
6957 aIter.Next();
6958 }
6959
6960 if ( (aP1.*pDirPt)() < (aP2.*pDirPt)() )
6961 {
6962 SwRect aRect( aP1, aP2 );
6963 // use parameter <pSubsLines> instead of global variable <gProp.pSSubsLines>.
6964 pSubsLines->AddLineRect( aRect, nullptr, SvxBorderLineStyle::SOLID,
6965 nullptr, nSubColor, gProp );
6966 }
6967 aP1 = aP2;
6968 (aP1.*pDirPtSet)( (aP1.*pDirPt)() + 1 );
6969 aP2 = rP2;
6970 }
6971}
6972
6973static std::vector<basegfx::B2DPolygon> lcl_CreatePageAreaDelimiterPolygons(const SwRect& rRect)
6974{
6975 std::vector<basegfx::B2DPolygon> aPolygons;
6976
6977 double nLineLength = 200.0; // in Twips
6978
6979 Point aPoints[] = { rRect.TopLeft(), rRect.TopRight(), rRect.BottomRight(), rRect.BottomLeft() };
6980 double const aXOffDirs[] = { -1.0, 1.0, 1.0, -1.0 };
6981 double const aYOffDirs[] = { -1.0, -1.0, 1.0, 1.0 };
6982
6983 // Actually loop over the corners to create the two lines
6984 for ( int i = 0; i < 4; i++ )
6985 {
6986 basegfx::B2DVector aHorizVector( aXOffDirs[i], 0.0 );
6987 basegfx::B2DVector aVertVector( 0.0, aYOffDirs[i] );
6988
6989 basegfx::B2DPoint aBPoint( aPoints[i].getX(), aPoints[i].getY() );
6990
6991 basegfx::B2DPolygon aPolygon;
6992 aPolygon.append( aBPoint + aHorizVector * nLineLength );
6993 aPolygon.append( aBPoint );
6994 aPolygon.append( aBPoint + aVertVector * nLineLength );
6995
6996 aPolygons.emplace_back(aPolygon);
6997 }
6998
6999 return aPolygons;
7000}
7001
7003 const std::vector<basegfx::B2DPolygon>& rPolygons)
7004{
7006
7008 for (size_t i = 0; i < rPolygons.size(); ++i)
7009 aSeq[i] = new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(rPolygons[i], aLineColor);
7010
7011 return aSeq;
7012}
7013
7014static std::vector<basegfx::B2DPolygon> lcl_CreateRectangleDelimiterPolygons(const SwRect& rRect)
7015{
7016 std::vector<basegfx::B2DPolygon> aRet(1);
7017 aRet[0].append( basegfx::B2DPoint( rRect.Left(), rRect.Top() ) );
7018 aRet[0].append( basegfx::B2DPoint( rRect.Right(), rRect.Top() ) );
7019 aRet[0].append( basegfx::B2DPoint( rRect.Right(), rRect.Bottom() ) );
7020 aRet[0].append( basegfx::B2DPoint( rRect.Left(), rRect.Bottom() ) );
7021 aRet[0].setClosed( true );
7022 return aRet;
7023}
7024
7026 const SwRect& rRect )
7027{
7029}
7030
7032 const SwRect& rRect )
7033{
7035
7037 double nLineLength = 100.0; // in Twips
7038
7039 Point aPoints[] = { rRect.TopLeft(), rRect.TopRight(), rRect.BottomRight(), rRect.BottomLeft() };
7040 double const aXOffDirs[] = { 1.0, -1.0, -1.0, 1.0 };
7041 double const aYOffDirs[] = { 1.0, 1.0, -1.0, -1.0 };
7042
7043 // Actually loop over the corners to create the two lines
7044 for ( int i = 0; i < 4; i++ )
7045 {
7046 basegfx::B2DVector aHorizVector( aXOffDirs[i], 0.0 );
7047 basegfx::B2DVector aVertVector( 0.0, aYOffDirs[i] );
7048
7049 basegfx::B2DPoint aBPoint( aPoints[i].getX(), aPoints[i].getY() );
7050
7051 basegfx::B2DPolygon aPolygon;
7052 aPolygon.append( aBPoint + aHorizVector * nLineLength );
7053 aPolygon.append( aBPoint );
7054 aPolygon.append( aBPoint + aVertVector * nLineLength );
7055
7057 std::move(aPolygon), aLineColor );
7058 }
7059
7060 return aSeq;
7061}
7062
7063std::vector<basegfx::B2DPolygon> SwPageFrame::GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const
7064{
7065 std::vector<basegfx::B2DPolygon> aPolygons;
7066
7067 if (!rViewShell.GetViewOptions()->IsDocBoundaries())
7068 return aPolygons;
7069
7070 const SwFrame* pLay = Lower();
7071 const SwFrame* pFootnoteCont = nullptr;
7072 const SwFrame* pPageBody = nullptr;
7073 while ( pLay && !( pFootnoteCont && pPageBody ) )
7074 {
7075 if ( pLay->IsFootnoteContFrame( ) )
7076 pFootnoteCont = pLay;
7077 if ( pLay->IsBodyFrame() )
7078 pPageBody = pLay;
7079 pLay = pLay->GetNext();
7080 }
7081
7082 assert(pPageBody && "presumably this is impossible");
7083
7084 SwRect aArea( pPageBody->getFrameArea() );
7085 if ( pFootnoteCont )
7086 aArea.AddBottom( pFootnoteCont->getFrameArea().Bottom() - aArea.Bottom() );
7087
7088 if (aArea.IsEmpty())
7089 return aPolygons;
7090
7091 if (!rViewShell.GetViewOptions()->IsViewMetaChars())
7092 aPolygons = lcl_CreatePageAreaDelimiterPolygons(aArea);
7093 else
7094 aPolygons = lcl_CreateRectangleDelimiterPolygons(aArea);
7095
7096 return aPolygons;
7097}
7098
7100{
7101 if (gProp.pSGlobalShell->IsHeaderFooterEdit())
7102 return;
7103
7104 std::vector<basegfx::B2DPolygon> aPolygons = GetSubsidiaryLinesPolygons(*gProp.pSGlobalShell);
7105 if (aPolygons.empty())
7106 return;
7107
7109}
7110
7111static void lclAddSubsidiaryLinesBounds(const std::vector<basegfx::B2DPolygon>& rPolygons, RectangleVector& rRects)
7112{
7113 for (const auto& rPolygon : rPolygons)
7114 {
7115 tools::Rectangle aRect(vcl::unotools::rectangleFromB2DRectangle(rPolygon.getB2DRange()));
7116 aRect.expand(1);
7117 if (basegfx::utils::isRectangle(rPolygon) && aRect.GetWidth() > 4 && aRect.GetHeight() > 4)
7118 {
7119 // turn hairline rectangle into four non-overlapping blocks that cover the borders
7120 rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top()), Size(aRect.GetWidth(), 2)));
7121 rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top() + 2), Size(2, aRect.GetHeight() - 4)));
7122 rRects.emplace_back(tools::Rectangle(Point(aRect.Right() - 2, aRect.Top() + 2), Size(2, aRect.GetHeight() - 4)));
7123 rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top() + aRect.GetHeight() - 2), Size(aRect.GetWidth(), 2)));
7124 }
7125 else
7126 rRects.emplace_back(aRect);
7127 }
7128}
7129
7131{
7133
7134 const SwFrame *pLow = Lower();
7135 while (pLow)
7136 {
7137 if (pLow->getFrameArea().HasArea())
7138 {
7139 if (pLow->IsHeaderFrame() || pLow->IsFooterFrame())
7140 {
7141 static_cast<const SwHeadFootFrame*>(pLow)->AddSubsidiaryLinesBounds(rViewShell, rRects);
7142 }
7143 }
7144 pLow = pLow->GetNext();
7145 }
7146}
7147
7149 const SwRect & ) const
7150{
7151 const SwFrame* pLay = Lower();
7152 const SwFrame* pFootnoteCont = nullptr;
7153 const SwFrame* pColBody = nullptr;
7154 while ( pLay && !( pFootnoteCont && pColBody ) )
7155 {
7156 if ( pLay->IsFootnoteContFrame( ) )
7157 pFootnoteCont = pLay;
7158 if ( pLay->IsBodyFrame() )
7159 pColBody = pLay;
7160 pLay = pLay->GetNext();
7161 }
7162
7163 assert(pColBody && "presumably this is impossible");
7164
7165 SwRect aArea( pColBody->getFrameArea() );
7166
7167 // #i3662# - enlarge top of column body frame's printing area
7168 // in sections to top of section frame.
7169 const bool bColInSection = GetUpper()->IsSctFrame();
7170 if ( bColInSection )
7171 {
7172 if ( IsVertical() )
7173 aArea.Right( GetUpper()->getFrameArea().Right() );
7174 else
7175 aArea.Top( GetUpper()->getFrameArea().Top() );
7176 }
7177
7178 if ( pFootnoteCont )
7179 aArea.AddBottom( pFootnoteCont->getFrameArea().Bottom() - aArea.Bottom() );
7180
7181 ::SwAlignRect( aArea, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
7182
7183 if ( !gProp.pSGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
7185 else
7187}
7188
7190 const SwRect & rRect ) const
7191{
7192 if (!gProp.pSGlobalShell->GetViewOptions()->IsSectionBoundaries())
7193 return;
7194
7195 const bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrame();
7196 if ( bNoLowerColumn )
7197 {
7199 }
7200}
7201
7207 const SwRect & ) const
7208{
7209}
7210
7211std::vector<basegfx::B2DPolygon> SwHeadFootFrame::GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const
7212{
7213 std::vector<basegfx::B2DPolygon> aPolygons;
7214
7215 if (!rViewShell.GetViewOptions()->IsDocBoundaries())
7216 return aPolygons;
7217
7218 SwRect aArea( getFramePrintArea() );
7219 aArea.Pos() += getFrameArea().Pos();
7220 if (!rViewShell.GetViewOptions()->IsViewMetaChars( ))
7221 aPolygons = lcl_CreatePageAreaDelimiterPolygons(aArea);
7222 else
7223 aPolygons = lcl_CreateRectangleDelimiterPolygons(aArea);
7224
7225 return aPolygons;
7226}
7227
7229{
7230 if (!gProp.pSGlobalShell->IsHeaderFooterEdit())
7231 return;
7232
7233 std::vector<basegfx::B2DPolygon> aPolygons = GetSubsidiaryLinesPolygons(*gProp.pSGlobalShell);
7234 if (aPolygons.empty())
7235 return;
7236
7238}
7239
7241{
7243}
7244
7250 const SwRect & ) const
7251{
7252}
7253
7259 const SwRect & ) const
7260{
7261}
7262
7264 const SwRect &rRect ) const
7265{
7266 bool bNewTableModel = false;
7267
7268 // #i29550#
7269 if ( IsTabFrame() || IsCellFrame() || IsRowFrame() )
7270 {
7271 const SwTabFrame* pTabFrame = FindTabFrame();
7272 if ( pTabFrame->IsCollapsingBorders() )
7273 return;
7274
7275 bNewTableModel = pTabFrame->GetTable()->IsNewModel();
7276 // in the new table model, we have an early return for all cell-related
7277 // frames, except from non-covered table cells
7278 if ( bNewTableModel )
7279 if ( IsTabFrame() ||
7280 IsRowFrame() ||
7281 ( IsCellFrame() && IsCoveredCell() ) )
7282 return;
7283 }
7284
7285 const bool bFlys = pPage->GetSortedObjs() != nullptr;
7286
7287 const bool bCell = IsCellFrame();
7288 // #i3662# - use frame area for cells for section use also frame area
7289 const bool bUseFrameArea = bCell || IsSctFrame();
7290 SwRect aOriginal( bUseFrameArea ? getFrameArea() : getFramePrintArea() );
7291 if ( !bUseFrameArea )
7292 aOriginal.Pos() += getFrameArea().Pos();
7293
7294 ::SwAlignRect( aOriginal, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
7295
7296 if ( !aOriginal.Overlaps( rRect ) )
7297 return;
7298
7299 SwRect aOut( aOriginal );
7300 aOut.Intersection_( rRect );
7301
7302 const SwTwips nRight = aOut.Right();
7303 const SwTwips nBottom= aOut.Bottom();
7304
7305 const Point aRT( nRight, aOut.Top() );
7306 const Point aRB( nRight, nBottom );
7307 const Point aLB( aOut.Left(), nBottom );
7308
7309 SubColFlags nSubColor = ( bCell || IsRowFrame() )
7310 ? SubColFlags::Tab
7311 : ( IsInSct()
7312 ? SubColFlags::Sect
7313 : ( IsInFly() ? SubColFlags::Fly : SubColFlags::Page ) );
7314
7315 // collect body, header, footer, footnote and section
7316 // sub-lines in <pSpecSubsLine> array.
7317 const bool bSpecialSublines = IsBodyFrame() || IsHeaderFrame() || IsFooterFrame() ||
7319 SwLineRects *const pUsedSubsLines = bSpecialSublines
7320 ? gProp.pSSpecSubsLines.get() : gProp.pSSubsLines.get();
7321
7322 // NOTE: for cell frames only left and right (horizontal layout) respectively
7323 // top and bottom (vertical layout) lines painted.
7324 // NOTE2: this does not hold for the new table model!!! We paint the top border
7325 // of each non-covered table cell.
7326 const bool bVert = IsVertical();
7327 if ( bFlys )
7328 {
7329 // add control for drawing left and right lines
7330 if ( !bCell || bNewTableModel || !bVert )
7331 {
7332 if ( aOriginal.Left() == aOut.Left() )
7333 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor, pUsedSubsLines );
7334 // in vertical layout set page/column break at right
7335 if ( aOriginal.Right() == nRight )
7336 ::lcl_RefreshLine( this, pPage, aRT, aRB, nSubColor, pUsedSubsLines );
7337 }
7338 // adjust control for drawing top and bottom lines
7339 if ( !bCell || bNewTableModel || bVert )
7340 {
7341 if ( aOriginal.Top() == aOut.Top() )
7342 // in horizontal layout set page/column break at top
7343 ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT, nSubColor, pUsedSubsLines );
7344 if ( aOriginal.Bottom() == nBottom )
7345 ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
7346 pUsedSubsLines );
7347 }
7348 }
7349 else
7350 {
7351 // add control for drawing left and right lines
7352 if ( !bCell || bNewTableModel || !bVert )
7353 {
7354 if ( aOriginal.Left() == aOut.Left() )
7355 {
7356 const SwRect aRect( aOut.Pos(), aLB );
7357 pUsedSubsLines->AddLineRect( aRect, nullptr,
7358 SvxBorderLineStyle::SOLID, nullptr, nSubColor, gProp );
7359 }
7360 // in vertical layout set page/column break at right
7361 if ( aOriginal.Right() == nRight )
7362 {
7363 const SwRect aRect( aRT, aRB );
7364 pUsedSubsLines->AddLineRect( aRect, nullptr,
7365 SvxBorderLineStyle::SOLID, nullptr, nSubColor, gProp );
7366 }
7367 }
7368 // adjust control for drawing top and bottom lines
7369 if ( !bCell || bNewTableModel || bVert )
7370 {
7371 if ( aOriginal.Top() == aOut.Top() )
7372 {
7373 // in horizontal layout set page/column break at top
7374 const SwRect aRect( aOut.Pos(), aRT );
7375 pUsedSubsLines->AddLineRect( aRect, nullptr,
7376 SvxBorderLineStyle::SOLID, nullptr, nSubColor, gProp );
7377 }
7378 if ( aOriginal.Bottom() == nBottom )
7379 {
7380 const SwRect aRect( aLB, aRB );
7381 pUsedSubsLines->AddLineRect( aRect, nullptr,
7382 SvxBorderLineStyle::SOLID, nullptr, nSubColor, gProp );
7383 }
7384 }
7385 }
7386}
7387
7392void SwPageFrame::RefreshExtraData( const SwRect &rRect ) const
7393{
7394 const SwLineNumberInfo &rInfo = GetFormat()->GetDoc()->GetLineNumberInfo();
7395 bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
7396 || static_cast<sal_Int16>(SW_MOD()->GetRedlineMarkPos()) != text::HoriOrientation::NONE;
7397
7398 SwRect aRect( rRect );
7399 ::SwAlignRect( aRect, gProp.pSGlobalShell, gProp.pSGlobalShell->GetOut() );
7400 if ( !aRect.HasArea() )
7401 return;
7402
7404
7405 if ( bLineInFly && GetSortedObjs() )
7406 for (SwAnchoredObject* pAnchoredObj : *GetSortedObjs())
7407 {
7408 if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
7409 {
7410 if ( pFly->getFrameArea().Top() <= aRect.Bottom() &&
7411 pFly->getFrameArea().Bottom() >= aRect.Top() )
7412 pFly->RefreshExtraData( aRect );
7413 }
7414 }
7415}
7416
7417void SwLayoutFrame::RefreshExtraData( const SwRect &rRect ) const
7418{
7419
7420 const SwLineNumberInfo &rInfo = GetFormat()->GetDoc()->GetLineNumberInfo();
7421 bool bLineInBody = rInfo.IsPaintLineNumbers(),
7422 bLineInFly = bLineInBody && rInfo.IsCountInFlys(),
7423 bRedLine = static_cast<sal_Int16>(SW_MOD()->GetRedlineMarkPos())!=text::HoriOrientation::NONE;
7424
7425 const SwContentFrame *pCnt = ContainsContent();
7426 while ( pCnt && IsAnLower( pCnt ) )
7427 {
7428 if ( pCnt->IsTextFrame() && ( bRedLine ||
7429 ( !pCnt->IsInTab() &&
7430 ((bLineInBody && pCnt->IsInDocBody()) ||
7431 (bLineInFly && pCnt->IsInFly())) ) ) &&
7432 pCnt->getFrameArea().Top() <= rRect.Bottom() &&
7433 pCnt->getFrameArea().Bottom() >= rRect.Top() )
7434 {
7435 static_cast<const SwTextFrame*>(pCnt)->PaintExtraData( rRect );
7436 }
7437 if ( bLineInFly && pCnt->GetDrawObjs() )
7438 for (SwAnchoredObject* pAnchoredObj : *pCnt->GetDrawObjs())
7439 {
7440 if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
7441 {
7442 if ( pFly->IsFlyInContentFrame() &&
7443 pFly->getFrameArea().Top() <= rRect.Bottom() &&
7444 pFly->getFrameArea().Bottom() >= rRect.Top() )
7445 pFly->RefreshExtraData( rRect );
7446 }
7447 }
7448 pCnt = pCnt->GetNextContentFrame();
7449 }
7450}
7451
7463{
7464 const SvxBrushItem* pBrushItem;
7465 std::optional<Color> xDummyColor;
7466 SwRect aDummyRect;
7468
7469 if ( GetBackgroundBrush( aFillAttributes, pBrushItem, xDummyColor, aDummyRect, true, /*bConsiderTextBox=*/false) )
7470 {
7471 if(aFillAttributes && aFillAttributes->isUsed())
7472 {
7473 // let SdrAllFillAttributesHelper do the average color calculation
7474 return Color(aFillAttributes->getAverageColor(aGlobalRetoucheColor.getBColor()));
7475 }
7476 else if(pBrushItem)
7477 {
7478 OUString referer;
7480 if (sh1 != nullptr) {
7481 SfxObjectShell * sh2 = sh1->GetDoc()->GetPersist();
7482 if (sh2 != nullptr && sh2->HasName()) {
7483 referer = sh2->GetMedium()->GetName();
7484 }
7485 }
7486 const Graphic* pGraphic = pBrushItem->GetGraphic(referer);
7487
7488 if(pGraphic)
7489 {
7490 // #29105# when a graphic is set, it may be possible to calculate a single
7491 // color which looks good in all places of the graphic. Since it is
7492 // planned to have text edit on the overlay one day and the fallback
7493 // to aGlobalRetoucheColor returns something useful, just use that
7494 // for now.
7495 }
7496 else
7497 {
7498 // not a graphic, use (hopefully) initialized color
7499 return pBrushItem->GetColor();
7500 }
7501 }
7502 }
7503
7504 return aGlobalRetoucheColor;
7505}
7506
7509{
7510 static vcl::Font aEmptyPgFont = []()
7511 {
7512 vcl::Font tmp;
7513 tmp.SetFontSize( Size( 0, 80 * 20 )); // == 80 pt
7514 tmp.SetWeight( WEIGHT_BOLD );
7515 tmp.SetStyleName(OUString());
7516 tmp.SetFamilyName("Helvetica");
7517 tmp.SetFamily( FAMILY_SWISS );
7518 tmp.SetTransparent( true );
7519 tmp.SetColor( COL_GRAY );
7520 return tmp;
7521 }();
7522
7523 return aEmptyPgFont;
7524}
7525
7533void SwFrame::Retouch( const SwPageFrame * pPage, const SwRect &rRect ) const
7534{
7535 if ( gProp.bSFlyMetafile )
7536 return;
7537
7538 OSL_ENSURE( GetUpper(), "Retouche try without Upper." );
7539 OSL_ENSURE( getRootFrame()->GetCurrShell() && gProp.pSGlobalShell->GetWin(), "Retouche on a printer?" );
7540
7541 SwRect aRetouche( GetUpper()->GetPaintArea() );
7542 aRetouche.Top( getFrameArea().Top() + getFrameArea().Height() );
7543 aRetouche.Intersection( gProp.pSGlobalShell->VisArea() );
7544
7545 if ( aRetouche.HasArea() )
7546 {
7547 //Omit the passed Rect. To do this, we unfortunately need a region to
7548 //cut out.
7549 SwRegionRects aRegion( aRetouche );
7550 aRegion -= rRect;
7552
7553 // #i16816# tagged pdf support
7554 SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pSh->GetOut() );
7555
7556 for ( size_t i = 0; i < aRegion.size(); ++i )
7557 {
7558 const SwRect &rRetouche = aRegion[i];
7559
7560 GetUpper()->PaintBaBo( rRetouche, pPage );
7561
7562 //Hell and Heaven need to be refreshed too.
7563 //To avoid recursion my retouch flag needs to be reset first!
7564 ResetRetouche();
7565 if ( rRetouche.HasArea() )
7566 {
7567 const Color aPageBackgrdColor(pPage->GetDrawBackgroundColor());
7569 // --> OD #i76669#
7570 SwViewObjectContactRedirector aSwRedirector( *pSh );
7571 // <--
7572
7573 pSh->Imp()->PaintLayer( rIDDMA.GetHellId(), nullptr,
7574 *pPage, rRetouche, &aPageBackgrdColor,
7575 pPage->IsRightToLeft(),
7576 &aSwRedirector );
7577 pSh->Imp()->PaintLayer( rIDDMA.GetHeavenId(), nullptr,
7578 *pPage, rRetouche, &aPageBackgrdColor,
7579 pPage->IsRightToLeft(),
7580 &aSwRedirector );
7581 }
7582
7583 SetRetouche();
7584
7585 //Because we leave all paint areas, we need to refresh the
7586 //subsidiary lines.
7587 pPage->RefreshSubsidiary( rRetouche );
7588 }
7589 }
7591 ResetRetouche();
7592}
7593
7641 const SvxBrushItem* & rpBrush,
7642 std::optional<Color>& rxCol,
7643 SwRect &rOrigRect,
7644 bool bLowerMode,
7645 bool bConsiderTextBox ) const
7646{
7647 const SwFrame *pFrame = this;
7649 const SwViewOption *pOpt = pSh->GetViewOptions();
7650 rpBrush = nullptr;
7651 rxCol.reset();
7652 do
7653 {
7654 if ( pFrame->IsPageFrame() && !pOpt->IsPageBack() )
7655 return false;
7656
7658 {
7659 bool bHandledTextBox = false;
7660 if (pFrame->IsFlyFrame() && bConsiderTextBox)
7661 {
7662 const SwFlyFrame* pFlyFrame = static_cast<const SwFlyFrame*>(pFrame);
7663 SwFrameFormat* pShape
7665 if (pShape)
7666 {
7667 SdrObject* pObject = pShape->FindRealSdrObject();
7668 if (pObject)
7669 {
7670 // Work with the fill attributes of the shape of the fly frame.
7671 rFillAttributes =
7672 std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(
7673 pObject->GetMergedItemSet());
7674 bHandledTextBox = true;
7675 }
7676 }
7677 }
7678
7679 if (!bHandledTextBox)
7680 rFillAttributes = pFrame->getSdrAllFillAttributesHelper();
7681 }
7682 const SvxBrushItem &rBack = pFrame->GetAttrSet()->GetBackground();
7683
7684 if( pFrame->IsSctFrame() )
7685 {
7686 const SwSection* pSection = static_cast<const SwSectionFrame*>(pFrame)->GetSection();
7687 // Note: If frame <pFrame> is a section of the index and
7688 // it its background color is "no fill"/"auto fill" and
7689 // it has no background graphic and
7690 // we are not in the page preview and
7691 // we are not in read-only mode and
7692 // option "index shadings" is set and
7693 // the output is not the printer
7694 // then set <rpCol> to the color of the index shading
7695 if( pSection && ( SectionType::ToxHeader == pSection->GetType() ||
7696 SectionType::ToxContent == pSection->GetType() ) &&
7697 (rBack.GetColor() == COL_TRANSPARENT) &&
7698 rBack.GetGraphicPos() == GPOS_NONE &&
7699 !pOpt->IsPagePreview() &&
7700 !pOpt->IsReadonly() &&
7701 // #114856# Form view
7702 !pOpt->IsFormView() &&
7703 pOpt->IsIndexShadings() &&
7704 !pOpt->IsPDFExport() &&
7705 pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
7706 {
7707 rxCol = pOpt->GetIndexShadingsColor();
7708 }
7709 }
7710
7711 // determine, if background draw of frame <pFrame> considers transparency
7712 // Status Quo: background transparency have to be
7713 // considered for fly frames
7714 const bool bConsiderBackgroundTransparency = pFrame->IsFlyFrame();
7715
7716 // #i125189# Do not base the decision for using the parent's fill style for this
7717 // frame when the new DrawingLayer FillAttributes are used on the SdrAllFillAttributesHelper
7718 // information. There the data is already optimized to no fill in the case that the
7719 // transparence is at 100% while no fill is the criteria for derivation
7720 bool bNewDrawingLayerFillStyleIsUsedAndNotNoFill(false);
7721
7722 if(rFillAttributes)
7723 {
7724 // the new DrawingLayer FillStyle is used
7725 if(rFillAttributes->isUsed())
7726 {
7727 // it's not drawing::FillStyle_NONE
7728 bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true;
7729 }
7730 else
7731 {
7732 // maybe optimized already when 100% transparency is used somewhere, need to test
7733 // XFillStyleItem directly from the model data
7734 const drawing::FillStyle eFillStyle(pFrame->GetAttrSet()->Get(XATTR_FILLSTYLE).GetValue());
7735
7736 if(drawing::FillStyle_NONE != eFillStyle)
7737 {
7738 bNewDrawingLayerFillStyleIsUsedAndNotNoFill = true;
7739 }
7740 }
7741 }
7742
7743 // add condition:
7744 // If <bConsiderBackgroundTransparency> is set - see above -,
7745 // return brush of frame <pFrame>, if its color is *not* "no fill"/"auto fill"
7746 if (
7747 // #i125189# Done when the new DrawingLayer FillAttributes are used and
7748 // not drawing::FillStyle_NONE (see above)
7749 bNewDrawingLayerFillStyleIsUsedAndNotNoFill ||
7750
7751 // done when SvxBrushItem is used
7752 rBack.GetColor().GetAlpha() == 255 || rBack.GetGraphicPos() != GPOS_NONE ||
7753
7754 // done when direct color is forced
7755 rxCol ||
7756
7757 // done when consider BG transparency and color is not completely transparent
7758 (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
7759 )
7760 {
7761 rpBrush = &rBack;
7762 if ( pFrame->IsPageFrame() && pSh->GetViewOptions()->getBrowseMode() )
7763 {
7764 rOrigRect = pFrame->getFrameArea();
7765 ::SwAlignRect(rOrigRect, pSh, pSh->GetOut());
7766 }
7767 else
7768 {
7769 if (pFrame->IsPageFrame()
7771 {
7772 rOrigRect = pFrame->getFrameArea();
7773 }
7774 else if (pFrame->getFrameArea().SSize() != pFrame->getFramePrintArea().SSize())
7775 {
7776 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFrame );
7777 const SwBorderAttrs &rAttrs = *aAccess.Get();
7778 ::lcl_CalcBorderRect( rOrigRect, pFrame, rAttrs, false, gProp );
7779 }
7780 else
7781 {
7782 rOrigRect = pFrame->getFramePrintArea();
7783 rOrigRect += pFrame->getFrameArea().Pos();
7784 }
7785 }
7786
7787 return true;
7788 }
7789
7790 if ( bLowerMode )
7791 {
7792 // Do not try to get background brush from parent (anchor/upper)
7793 return false;
7794 }
7795
7796 // get parent frame - anchor or upper - for next loop
7797 if ( pFrame->IsFlyFrame() )
7798 {
7799 pFrame = static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame();
7800 }
7801 else
7802 {
7803 pFrame = pFrame->GetUpper();
7804 }
7805 } while ( pFrame );
7806
7807 return false;
7808}
7809
7811 vcl::Window *pW, sal_uInt16 nZoom )
7812{
7813 pSh->mpOut = pO;
7814 pSh->mpWin = pW;
7815 pSh->mpOpt->SetZoom( nZoom );
7816}
7817
7818Graphic SwFrameFormat::MakeGraphic( ImageMap*, const sal_uInt32 /*nMaximumQuadraticPixels*/, const std::optional<Size>& /*rTargetDPI*/ )
7819{
7820 return Graphic();
7821}
7822
7823Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap, const sal_uInt32 /*nMaximumQuadraticPixels*/, const std::optional<Size>& /*rTargetDPI*/ )
7824{
7825 Graphic aRet;
7826 //search any Fly!
7827 SwIterator<SwFrame,SwFormat> aIter( *this );
7828 SwFrame *pFirst = aIter.First();
7829 SwViewShell *const pSh =
7830 pFirst ? pFirst->getRootFrame()->GetCurrShell() : nullptr;
7831 if (nullptr != pSh)
7832 {
7833 SwViewShell *pOldGlobal = gProp.pSGlobalShell;
7834 gProp.pSGlobalShell = pSh;
7835
7836 bool bNoteURL = pMap &&
7837 SfxItemState::SET != GetAttrSet().GetItemState( RES_URL );
7838 if( bNoteURL )
7839 {
7840 OSL_ENSURE( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
7841 pNoteURL = new SwNoteURL;
7842 }
7843 SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pFirst);
7844
7845 OutputDevice *pOld = pSh->GetOut();
7847 pDev->EnableOutput( false );
7848
7849 GDIMetaFile aMet;
7850 MapMode aMap( pOld->GetMapMode().GetMapUnit() );
7851 pDev->SetMapMode( aMap );
7852 aMet.SetPrefMapMode( aMap );
7853
7854 ::SwCalcPixStatics( pSh->GetOut() );
7855 aMet.SetPrefSize( pFly->getFrameArea().SSize() );
7856
7857 aMet.Record( pDev.get() );
7858 pDev->SetLineColor();
7859 pDev->SetFillColor();
7860 pDev->SetFont( pOld->GetFont() );
7861
7862 //Enlarge the rectangle if needed, so the border is painted too.
7863 SwRect aOut( pFly->getFrameArea() );
7864 SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFly );
7865 const SwBorderAttrs &rAttrs = *aAccess.Get();
7866 if ( rAttrs.CalcRightLine() )
7867 aOut.AddWidth(2*gProp.nSPixelSzW );
7868 if ( rAttrs.CalcBottomLine() )
7869 aOut.AddHeight(2*gProp.nSPixelSzH );
7870
7871 // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
7872 const vcl::Region aRepaintRegion(aOut.SVRect());
7873 pSh->DLPrePaint2(aRepaintRegion);
7874
7875 vcl::Window *pWin = pSh->GetWin();
7876 sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
7877 ::SetOutDevAndWin( pSh, pDev, nullptr, 100 );
7878 gProp.bSFlyMetafile = true;
7879 gProp.pSFlyMetafileOut = pWin->GetOutDev();
7880
7881 SwViewShellImp *pImp = pSh->Imp();
7882 gProp.pSFlyOnlyDraw = pFly;
7883 gProp.pSLines.reset(new SwLineRects);
7884
7885 // determine page, fly frame is on
7886 const SwPageFrame* pFlyPage = pFly->FindPageFrame();
7887 const Color aPageBackgrdColor(pFlyPage->GetDrawBackgroundColor());
7889 // --> OD #i76669#
7890 SwViewObjectContactRedirector aSwRedirector( *pSh );
7891 // <--
7892 pImp->PaintLayer( rIDDMA.GetHellId(), nullptr,
7893 *pFlyPage, aOut, &aPageBackgrdColor,
7894 pFlyPage->IsRightToLeft(),
7895 &aSwRedirector );
7896 gProp.pSLines->PaintLines( pDev, gProp );
7897 if ( pFly->IsFlyInContentFrame() )
7898 pFly->PaintSwFrame( *pDev, aOut );
7899 gProp.pSLines->PaintLines( pDev, gProp );
7900 pImp->PaintLayer( rIDDMA.GetHeavenId(), nullptr,
7901 *pFlyPage, aOut, &aPageBackgrdColor,
7902 pFlyPage->IsRightToLeft(),
7903 &aSwRedirector );
7904 gProp.pSLines->PaintLines( pDev, gProp );
7905 gProp.pSLines.reset();
7906 gProp.pSFlyOnlyDraw = nullptr;
7907
7908 gProp.pSFlyMetafileOut = nullptr;
7909 gProp.bSFlyMetafile = false;
7910 ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
7911
7912 // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
7913 pSh->DLPostPaint2(true);
7914
7915 aMet.Stop();
7916 aMet.Move( -pFly->getFrameArea().Left(), -pFly->getFrameArea().Top() );
7917 aRet = Graphic( aMet );
7918
7919 if( bNoteURL )
7920 {
7921 OSL_ENSURE( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
7922 delete pNoteURL;
7923 pNoteURL = nullptr;
7924 }
7925 gProp.pSGlobalShell = pOldGlobal;
7926 }
7927 return aRet;
7928}
7929
7930Graphic SwDrawFrameFormat::MakeGraphic( ImageMap*, const sal_uInt32 nMaximumQuadraticPixels, const std::optional<Size>& rTargetDPI )
7931{
7932 Graphic aRet;
7934 if ( pMod )
7935 {
7936 SdrObject *pObj = FindSdrObject();
7937 SdrView aView( *pMod );
7938 SdrPageView *pPgView = aView.ShowSdrPage(aView.GetModel().GetPage(0));
7939 aView.MarkObj( pObj, pPgView );
7940 aRet = aView.GetMarkedObjBitmapEx(/*bNoVDevIfOneBmpMarked=*/false, nMaximumQuadraticPixels, rTargetDPI);
7941 aView.HideSdrPage();
7942 }
7943 return aRet;
7944}
7945
7946/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
DrawModeFlags
std::shared_ptr< SwFrameControl > SwFrameControlPtr
sal_Int32 nLineWidth
SwViewShell & mrViewShell
SvxBorderLineStyle
SvxGraphicPosition
GPOS_MT
GPOS_LT
GPOS_RT
GPOS_NONE
GPOS_MM
GPOS_TILED
GPOS_AREA
GPOS_MB
GPOS_LB
GPOS_LM
GPOS_RM
GPOS_RB
const StyleSettings & GetStyleSettings() const
static bool GetLayoutRTL()
static OutputDevice * GetDefaultDevice()
static const AllSettings & GetSettings()
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
const Size & GetSizePixel() const
Size GetSizePixel() const
bool Erase(const Color &rFillColor)
Color GetRGBColor() const
basegfx::BColor getBColor() const
sal_uInt8 GetAlpha() const
void ApplyTintOrShade(sal_Int16 n100thPercent)
bool IsTransparent() const
void Move(tools::Long nX, tools::Long nY)
void SetPrefMapMode(const MapMode &rMapMode)
void Record(OutputDevice *pOutDev)
void SetPrefSize(const Size &rSize)
bool IsTransparent() const
sal_uInt8 GetAlpha() const
void SetGraphic(const Graphic &rGraphic)
const Graphic & GetGraphic() const
GraphicType GetType() const
const GraphicAttr & GetAttr() const
bool IsTransparent() const
void DrawTiled(OutputDevice &rOut, const tools::Rectangle &rArea, const Size &rSize, const Size &rOffset, int nTileCacheSize1D=128)
OUString getOriginURL() const
bool IsSupportedGraphic() const
GraphicType GetType() const
static void DrawEx(OutputDevice &rOutDev, const OUString &rText, vcl::Font &rFont, const BitmapEx &rBitmap, const Point &rDestPt, const Size &rDestSize)
virtual SfxPrinter * getPrinter(bool bCreate) const =0
Return the printer set at the document.
virtual SdrLayerID GetHellId() const =0
virtual SdrLayerID GetHeavenId() const =0
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
Provides access to settings of a document.
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
const Fraction & GetScaleX() const
MapUnit GetMapUnit() const
const Fraction & GetScaleY() const
GDIMetaFile * GetConnectMetaFile() const
basegfx::B2DHomMatrix GetViewTransformation() const
const vcl::Font & GetFont() const
float GetDPIScaleFactor() const
void SetFont(const vcl::Font &rNewFont)
basegfx::B2DHomMatrix GetInverseViewTransformation() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void DrawRect(const tools::Rectangle &rRect)
void DrawLine(const Point &rStartPt, const Point &rEndPt)
void DrawHatch(const tools::PolyPolygon &rPolyPoly, const Hatch &rHatch)
void SetLineColor()
void DrawPolygon(const tools::Polygon &rPoly)
void SetClipRegion()
void SetFillColor()
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
const MapMode & GetMapMode() const
void SetTextFillColor()
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
void SetDrawMode(DrawModeFlags nDrawMode)
OutDevType GetOutDevType() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
DrawModeFlags GetDrawMode() const
void DrawTransparent(const tools::PolyPolygon &rPolyPoly, sal_uInt16 nTransparencePercent)
void IntersectClipRegion(const tools::Rectangle &rRect)
const Color & GetFillColor() const
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
BitmapEx GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked=false, const sal_uInt32 nMaximumQuadraticPixels=500000, const std::optional< Size > &rTargetDPI=std::nullopt) const
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
const SdrPage * GetPage(sal_uInt16 nPgNum) const
void HideSdrPage() override
SdrPageView * ShowSdrPage(SdrPage *pPage) override
sal_uInt32 GetOrdNumDirect() const
sal_uInt32 GetOrdNum() const
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual SdrLayerID GetLayer() const
void DrawPageViewGrid(OutputDevice &rOut, const tools::Rectangle &rRect, Color aColor=COL_BLACK)
SdrPage * GetPage() const
SdrPageView * GetSdrPageView() const
SdrModel & GetModel() const
bool IsGridVisible() const
bool GetValue() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
const OUString & GetName() const
bool IsInGenerateAndStoreThumbnail() const
bool HasName() const
SfxMedium * GetMedium() const
SfxObjectCreateMode GetCreateMode() const
bool IsInPlaceActive() const
static void Reschedule()
static SfxProgress * GetActiveProgress(SfxObjectShell const *pDocSh=nullptr)
StylesHighlighterColorMap & GetStylesHighlighterParaColorMap()
constexpr tools::Long getHeight() const
constexpr tools::Long Height() const
constexpr tools::Long getWidth() const
constexpr tools::Long Width() const
const Color & GetDialogTextColor() const
bool GetHighContrastMode() const
const editeng::SvxBorderLine * GetTop() const
sal_Int16 CalcLineSpace(SvxBoxItemLine nLine, bool bEvenIfNoLine=false, bool bAllowNegative=false) const
const editeng::SvxBorderLine * GetRight() const
const editeng::SvxBorderLine * GetLeft() const
sal_Int16 GetDistance(SvxBoxItemLine nLine, bool bAllowNegative=false) const
const editeng::SvxBorderLine * GetBottom() const
const GraphicObject * GetGraphicObject(OUString const &referer=OUString()) const
const Color & GetColor() const
const Graphic * GetGraphic(OUString const &referer=OUString()) const
SvxGraphicPosition GetGraphicPos() const
sal_uInt16 GetWidth() const
const Color & GetColor() const
sal_uInt16 CalcShadowSpace(SvxShadowItemSide nShadow) const
void SetLocation(SvxShadowLocation eNew)
SvxShadowLocation GetLocation() const
wrapper class for the positioning of Writer fly frames and drawing objects
const SwFrame * GetAnchorFrame() const
SwFrame * AnchorFrame()
virtual const SwFlyFrame * DynCastFlyFrame() const
const SdrObject * GetDrawObj() const
const SvxBrushItem & GetBackground(bool=true) const
Definition: frmatr.hxx:70
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
The SwBodyFrame doesn't print any subsidiary line: it's bounds are painted either by the parent page ...
Definition: paintfrm.cxx:7206
SwBorderAttrs * Get()
Definition: frmtool.cxx:2696
bool JoinedWithNext(const SwFrame &_rFrame) const
Definition: frmtool.cxx:2616
sal_uInt16 CalcRightLine() const
Definition: frmtool.hxx:530
void SetGetCacheLine(bool bNew) const
Definition: frmtool.hxx:502
bool JoinedWithPrev(const SwFrame &_rFrame, const SwFrame *_pPrevFrame=nullptr) const
Definition: frmtool.cxx:2604
const SvxBoxItem & GetBox() const
Definition: frmtool.hxx:399
sal_uInt16 GetTopLine(const SwFrame &_rFrame, const SwFrame *_pPrevFrame=nullptr) const
Definition: frmtool.hxx:487
sal_uInt16 GetBottomLine(const SwFrame &_rFrame) const
Definition: frmtool.hxx:496
const SvxShadowItem & GetShadow() const
Definition: frmtool.hxx:400
bool IsLine() const
Definition: frmtool.hxx:554
sal_uInt16 CalcBottomLine() const
Definition: frmtool.hxx:518
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:31
tools::Long GetLayoutRowSpan() const
Definition: tabfrm.cxx:5820
std::vector< const SwCellFrame * > GetCoveredCells() const
If this is a vertically merged cell, then looks up its covered cells.
Definition: tabfrm.cxx:5874
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: paintfrm.cxx:4034
virtual void PaintBreak() const override
Definition: paintfrm.cxx:3736
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
Definition: paintfrm.cxx:7148
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:67
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:59
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:120
Definition: doc.hxx:197
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:49
static bool HasParagraphDirectFormatting(const SwPosition &rPos)
Definition: doc.cxx:1869
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:190
SfxObjectShell * GetPersist() const
Definition: docnew.cxx:653
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:169
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:200
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
ContactObject for connection of formats as representatives of draw objects in SwClient and the object...
Definition: dcontact.hxx:305
const SwFrame * GetAnchorFrame(const SdrObject *_pDrawObj=nullptr) const
Definition: dcontact.cxx:804
virtual Graphic MakeGraphic(ImageMap *pMap=nullptr, const sal_uInt32 nMaximumQuadraticPixels=500000, const std::optional< Size > &rTargetDPI=std::nullopt) override
Definition: paintfrm.cxx:7930
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:61
SwFrameControlsManager & GetFrameControlsManager()
Definition: edtwin.cxx:6832
bool IsBackgroundBrushInherited() const
SwFlyFrameFormat::IsBackgroundBrushInherited.
Definition: atrfrm.cxx:3305
virtual bool IsBackgroundTransparent() const override
SwFlyFrameFormat::IsBackgroundTransparent.
Definition: atrfrm.cxx:3264
virtual Graphic MakeGraphic(ImageMap *pMap=nullptr, const sal_uInt32 nMaximumQuadraticPixels=500000, const std::optional< Size > &rTargetDPI=std::nullopt) override
Definition: paintfrm.cxx:7823
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
void Validate() const
Definition: flyfrm.hxx:212
const SwVirtFlyDrawObj * GetVirtDrawObj() const
Definition: fly.cxx:3025
bool IsDeleted() const
Definition: flyfrm.hxx:221
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:3119
bool IsBackgroundTransparent() const
SwFlyFrame::IsBackgroundTransparent.
Definition: paintfrm.cxx:3904
size_t GetAuthor() const
Definition: flyfrm.hxx:224
bool IsLowerOf(const SwLayoutFrame *pUpper) const
Definition: fly.cxx:2392
static bool IsPaint(SdrObject *pObj, const SwViewShell *pSh)
Definition: paintfrm.cxx:3952
bool GetContour(tools::PolyPolygon &rContour, const bool _bForPaint=false) const
#i13147# - If called for paint and the <SwNoTextFrame> contains a graphic, load of intrinsic graphic ...
Definition: fly.cxx:2878
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:217
bool IsShowUnfloatButton(SwWrtShell *pWrtSh) const
Definition: fly.cxx:2014
void UpdateUnfloatButton(SwWrtShell *pWrtSh, bool bShow) const
Definition: fly.cxx:2092
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: paintfrm.cxx:4073
void PaintDecorators() const
Definition: paintfrm.cxx:4349
To take Asian or other languages into consideration, an SwFont object consists of 3 SwSubFonts (Latin...
Definition: swfont.hxx:135
SvxShadowLocation GetAbsShadowLocation(const bool bVertLayout, const bool bVertLayoutLRBT) const
Get the absolute shadow location dependent from orientation.
Definition: swfont.cxx:199
Degree10 GetOrientation(const bool bVertLayout=false, const bool bVertFormatLRBT=false) const
Definition: swfont.cxx:412
sal_uInt16 GetShadowWidth() const
Definition: swfont.hxx:385
const Color & GetShadowColor() const
Definition: swfont.hxx:384
const std::optional< editeng::SvxBorderLine > & GetAbsLeftBorder(const bool bVertLayout, const bool bVertLayoutLRBT) const
Definition: swfont.cxx:162
const std::optional< editeng::SvxBorderLine > & GetAbsTopBorder(const bool bVertLayout, const bool bVertLayoutLRBT) const
Definition: swfont.cxx:124
const std::optional< editeng::SvxBorderLine > & GetAbsBottomBorder(const bool bVertLayout, const bool bVertLayoutLRBT) const
Definition: swfont.cxx:143
const std::optional< editeng::SvxBorderLine > & GetAbsRightBorder(const bool bVertLayout, const bool bVertLayoutLRBT) const
Definition: swfont.cxx:181
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:48
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
This method is overridden in order to have no subsidiary lines around the footnotes containers.
Definition: paintfrm.cxx:7258
void dumpAsXml(xmlTextWriterPtr writer=nullptr) const override
Definition: paintfrm.cxx:5613
void PaintLine(const SwRect &, const SwPageFrame *) const
Paint footnote lines.
Definition: paintfrm.cxx:5572
virtual void PaintSwFrameShadowAndBorder(const SwRect &, const SwPageFrame *pPage, const SwBorderAttrs &) const override
Special implementation because of the footnote line.
Definition: paintfrm.cxx:5558
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
This method is overridden in order to have no subsidiary lines around the footnotes.
Definition: paintfrm.cxx:7249
const Color & GetLineColor() const
Definition: fmtclds.hxx:118
sal_uInt8 GetLineHeight() const
Definition: fmtclds.hxx:123
SvxBorderLineStyle GetLineStyle() const
Definition: fmtclds.hxx:116
sal_uLong GetLineWidth() const
Definition: fmtclds.hxx:117
SwColLineAdj GetLineAdj() const
Definition: fmtclds.hxx:120
bool IsContour() const
Definition: fmtsrnd.hxx:53
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
const SvxOpaqueItem & GetOpaque(bool=true) const
Definition: frmatr.hxx:104
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: format.cxx:712
const OUString & GetName() const
Definition: format.hxx:131
const SvxPrintItem & GetPrint(bool=true) const
Definition: frmatr.hxx:102
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
std::unique_ptr< SvxBrushItem > makeBackgroundBrushItem(bool=true) const
Definition: format.cxx:736
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool isFrameAreaPositionValid() const
Definition: frame.hxx:166
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
A container for the Header/Footer, PageBreak, and Outline Content Visibility controls.
void SetHeaderFooterControl(const SwPageFrame *pPageFrame, FrameControlType eType, Point aOffset)
void SetPageBreakControl(const SwPageFrame *pPageFrame)
void RemoveControlsByType(FrameControlType eType, const SwFrame *pFrame)
SwFrameControlPtr GetControl(FrameControlType eType, const SwFrame *pFrame)
Style of a layout element.
Definition: frmfmt.hxx:72
virtual bool supportsFullDrawingLayerFillAttributeSet() const override
Definition: atrfrm.cxx:2622
virtual Graphic MakeGraphic(ImageMap *pMap=nullptr, const sal_uInt32 nMaximumQuadraticPixels=500000, const std::optional< Size > &rTargetDPI=std::nullopt)
Definition: paintfrm.cxx:7818
virtual drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const override
Definition: atrfrm.cxx:3600
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2802
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:153
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool OnRightPage() const
Definition: frame.hxx:739
bool IsRowFrame() const
Definition: frame.hxx:1228
std::unique_ptr< drawinglayer::processor2d::BaseProcessor2D > CreateProcessor2D() const
Definition: paintfrm.cxx:5299
bool IsCellFrame() const
Definition: frame.hxx:1232
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed.
Definition: ssfrm.cxx:595
void Retouch(const SwPageFrame *pPage, const SwRect &rRect) const
Retouch for a section.
Definition: paintfrm.cxx:7533
bool IsFootnoteContFrame() const
Definition: frame.hxx:1204
bool IsTextFrame() const
Definition: frame.hxx:1240
void ProcessPrimitives(const drawinglayer::primitive2d::Primitive2DContainer &rSequence) const
Definition: paintfrm.cxx:5314
void PaintBaBo(const SwRect &, const SwPageFrame *pPage, const bool bOnlyTextBackground=false) const
Definition: paintfrm.cxx:6462
bool IsInDocBody() const
Definition: frame.hxx:949
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1117
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * GetNext()
Definition: frame.hxx:682
void ResetCompletePaint() const
Definition: frame.hxx:1004
bool supportsFullDrawingLayerFillAttributeSet() const
Definition: findfrm.cxx:795
bool IsPageFrame() const
Definition: frame.hxx:1184
bool IsColumnFrame() const
Definition: frame.hxx:1188
virtual bool IsCoveredCell() const
Definition: tabfrm.cxx:6346
bool IsVertLRBT() const
Definition: frame.hxx:989
bool IsTabFrame() const
Definition: frame.hxx:1224
SwFrameType GetType() const
Definition: frame.hxx:521
bool IsInFootnote() const
Definition: frame.hxx:955
bool IsHeaderFrame() const
Definition: frame.hxx:1196
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
bool IsRetoucheFrame() const
Definition: frame.hxx:1252
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:568
bool IsInTab() const
Definition: frame.hxx:961
void ResetRetouche() const
Definition: frame.hxx:1013
static SwCache & GetCache()
Definition: frame.hxx:523
SwFrame * GetLower()
Definition: findfrm.cxx:196
bool IsRightToLeft() const
Definition: frame.hxx:993
bool IsInFly() const
Definition: frame.hxx:967
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame,...
Definition: findfrm.cxx:762
void dumpInfosAsXml(xmlTextWriterPtr writer) const
Definition: xmldump.cxx:171
SwRect UnionFrame(bool bBorder=false) const
|* The unionframe is the framearea (getFrameArea()) of a frame expanded by the |* printarea,...
Definition: ssfrm.cxx:703
virtual void PaintSwFrameShadowAndBorder(const SwRect &, const SwPageFrame *pPage, const SwBorderAttrs &) const
Paints shadows and borders.
Definition: paintfrm.cxx:5324
bool IsFooterFrame() const
Definition: frame.hxx:1200
bool IsFootnoteFrame() const
Definition: frame.hxx:1208
bool GetBackgroundBrush(drawinglayer::attribute::SdrAllFillAttributesHelperPtr &rFillAttributes, const SvxBrushItem *&rpBrush, std::optional< Color > &rxColor, SwRect &rOrigRect, bool bLowerMode, bool bConsiderTextBox) const
Determine the background brush for the frame: the background brush is taken from it-self or from its ...
Definition: paintfrm.cxx:7639
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
void PaintSwFrameBackground(const SwRect &, const SwPageFrame *pPage, const SwBorderAttrs &, const bool bLowerMode=false, const bool bLowerBorder=false, const bool bOnlyTextBackground=false) const
Do not paint background for fly frames without a background brush by calling <PaintBaBo> at the page ...
Definition: paintfrm.cxx:6520
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const
Definition: xmldump.cxx:188
bool IsCompletePaint() const
Definition: frame.hxx:605
bool IsVertical() const
Definition: frame.hxx:979
SwRootFrame * getRootFrame()
Definition: frame.hxx:685
bool IsNoTextFrame() const
Definition: frame.hxx:1244
bool IsRetouche() const
Definition: frame.hxx:609
bool IsFlyFrame() const
Definition: frame.hxx:1216
bool IsContentFrame() const
Definition: frame.hxx:1236
SwFrame * GetPrev()
Definition: frame.hxx:683
bool IsSctFrame() const
Definition: frame.hxx:1220
bool IsVertLR() const
Definition: frame.hxx:985
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const
Definition: findfrm.cxx:779
void PaintBorderLine(const SwRect &, const SwRect &, const SwPageFrame *, const Color *pColor, const SvxBorderLineStyle=SvxBorderLineStyle::SOLID) const
Definition: paintfrm.cxx:4747
void SetDrawObjsAsDeleted(bool bDeleted)
Definition: paintfrm.cxx:4059
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const
Definition: unusedf.cxx:30
void SetRetouche() const
Definition: frame.hxx:1009
void dumpChildrenAsXml(xmlTextWriterPtr writer) const
Definition: xmldump.cxx:246
void PaintShadow(const SwRect &, SwRect &, const SwBorderAttrs &) const
Paints a shadow if the format requests so.
Definition: paintfrm.cxx:4710
bool IsLayoutFrame() const
Definition: frame.hxx:1176
bool IsBodyFrame() const
Definition: frame.hxx:1212
bool IsNeighbourFrame() const
Definition: frame.hxx:918
bool IsInSct() const
Definition: frame.hxx:973
std::vector< basegfx::B2DPolygon > GetSubsidiaryLinesPolygons(const SwViewShell &rViewShell) const
Definition: paintfrm.cxx:7211
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
Definition: paintfrm.cxx:7228
void AddSubsidiaryLinesBounds(const SwViewShell &rViewShell, RectangleVector &rRects) const
Definition: paintfrm.cxx:7240
TElementType * First()
Definition: calbck.hxx:372
The usage of LayAction is always the same:
Definition: layact.hxx:59
void Action(OutputDevice *pRenderContext)
Definition: layact.cxx:363
void SetReschedule(bool bNew)
Definition: layact.hxx:158
void SetComplete(bool bNew)
Definition: layact.hxx:154
void SetPaint(bool bNew)
Definition: layact.hxx:153
void Leave()
Definition: virtoutp.hxx:49
void Enter(SwViewShell *pShell, SwRect &rRect, bool bOn)
OD 27.09.2002 #103636# - change 2nd parameter <rRect> - no longer <const>
Definition: virtoutp.cxx:119
void SetOrgRect(SwRect const &rRect)
Definition: virtoutp.hxx:51
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const
Definition: paintfrm.cxx:7263
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:233
void RefreshExtraData(const SwRect &) const
Definition: paintfrm.cxx:7417
friend class SwFlowFrame
Definition: layfrm.hxx:38
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:401
void PaintColLines(const SwRect &, const SwFormatCol &, const SwPageFrame *) const
Paints the column separation line for the inner columns.
Definition: paintfrm.cxx:5627
virtual void PaintBreak() const
Definition: paintfrm.cxx:3822
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1917
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:72
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: paintfrm.cxx:3511
void RefreshLaySubsidiary(const SwPageFrame *, const SwRect &) const
Definition: paintfrm.cxx:6819
const SwFrame * Lower() const
Definition: layfrm.hxx:101
< purpose of derivation from SwClient: character style for displaying the numbers.
Definition: lineinfo.hxx:39
bool IsPaintLineNumbers() const
Definition: lineinfo.hxx:80
bool IsCountInFlys() const
Definition: lineinfo.hxx:86
bool HasAnimation() const
Definition: notxtfrm.cxx:1496
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:77
bool IsTransparent() const
Definition: notxtfrm.cxx:1439
Layout frame for SwNoTextNode, i.e. graphics and OLE nodes (including charts).
Definition: ndnotxt.hxx:30
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:165
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:116
svt::EmbeddedObjectRef & GetObject()
Definition: ndole.cxx:1063
const SdrObject * Bottom()
Definition: frmtool.cxx:2733
const SdrObject * Next()
Definition: frmtool.cxx:2760
void Current(const SdrObject *pNew)
Definition: frmtool.hxx:455
const SwPageFootnoteInfo & GetFootnoteInfo() const
Definition: pagedesc.hxx:205
Footnote information.
Definition: pagedesc.hxx:49
sal_uLong GetLineWidth() const
Definition: pagedesc.hxx:62
SwTwips GetTopDist() const
Definition: pagedesc.hxx:67
css::text::HorizontalAdjust GetAdj() const
Definition: pagedesc.hxx:66
const Color & GetLineColor() const
Definition: pagedesc.hxx:63
const Fraction & GetWidth() const
Definition: pagedesc.hxx:65
SvxBorderLineStyle GetLineStyle() const
Definition: pagedesc.hxx:64
A page of the document layout.
Definition: pagefrm.hxx:60
void PaintDecorators() const
Definition: paintfrm.cxx:3833
void RefreshExtraData(const SwRect &) const
Paint line number etc.
Definition: paintfrm.cxx:7392
void PaintGrid(OutputDevice const *pOut, SwRect const &rRect) const
Definition: paintfrm.cxx:5680
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:209
static const vcl::Font & GetEmptyPageFont()
create/return font used to paint the "empty page" string
Definition: paintfrm.cxx:7508
static void GetBorderAndShadowBoundRect(const SwRect &_rPageRect, const SwViewShell *_pViewShell, OutputDevice const *pRenderContext, SwRect &_orBorderAndShadowBoundRect, const bool bLeftShadow, const bool bRightShadow, const bool bRightSidebar)
get bound rectangle of border and shadow for repaints
Definition: paintfrm.cxx:6413
const SwPageFrame & GetFormatPage() const
Definition: pagechg.cxx:2470
bool m_bHasGrid
Definition: pagefrm.hxx:82
Color GetDrawBackgroundColor() const
SwPageFrame::GetDrawBackgroundColor.
Definition: paintfrm.cxx:7462
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:136
void RefreshSubsidiary(const SwRect &) const
Paint helper lines.
Definition: paintfrm.cxx:6786
bool IsLeftShadowNeeded() const
Definition: paintfrm.cxx:6028
void AddSubsidiaryLinesBounds(const SwViewShell &rShell, RectangleVector &rRects) const
Definition: paintfrm.cxx:7130
bool IsEmptyPage() const
Definition: pagefrm.hxx:161
sw::sidebarwindows::SidebarPosition SidebarPosition() const
asks the page on which side a margin should be shown, e.g for notes returns true for left side,...
Definition: pagechg.cxx:1462
static const sal_Int8 snShadowPxWidth
Definition: pagefrm.hxx:84
static void GetHorizontalShadowRect(const SwRect &_rPageRect, const SwViewShell *_pViewShell, OutputDevice const *pRenderContext, SwRect &_orBottomShadowRect, bool bPaintLeftShadow, bool bPaintRightShadow, bool bRightSidebar)
determine rectangle for horizontal page shadow
Definition: paintfrm.cxx:6044
std::vector< basegfx::B2DPolygon > GetSubsidiaryLinesPolygons(const SwViewShell &rViewShell) const
Definition: paintfrm.cxx:7063
virtual void PaintBreak() const override
Definition: paintfrm.cxx:3699
void PaintMarginArea(const SwRect &_rOutputRect, SwViewShell const *_pViewShell) const
paint margin area of a page
Definition: paintfrm.cxx:5990
static void PaintNotesSidebar(const SwRect &_rPageRect, SwViewShell *_pViewShell, sal_uInt16 nPageNum, bool bRight)
mod #i6193# paint sidebar for notes IMPORTANT: if you change the rects here, also change SwPostItMgr:...
Definition: paintfrm.cxx:6293
SwRect GetBoundRect(OutputDevice const *pOutputDevice) const
Definition: paintfrm.cxx:6440
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:147
static SwTwips GetSidebarBorderWidth(const SwViewShell *)
Definition: paintfrm.cxx:6455
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
Definition: paintfrm.cxx:7099
static void PaintNotesSidebarArrows(const Point &rMiddleFirst, const Point &rMiddleSecond, SwViewShell const *_pViewShell, const Color &rColorUp, const Color &rColorDown)
Definition: paintfrm.cxx:6389
bool IsRightShadowNeeded() const
Definition: paintfrm.cxx:6015
static void PaintBorderAndShadow(const SwRect &_rPageRect, const SwViewShell *_pViewShell, bool bPaintLeftShadow, bool bPaintRightShadow, bool bRightSidebar)
paint page border and shadow
Definition: paintfrm.cxx:6135
static void Add(SwViewShell *pSh, const SwRect &rNew)
Definition: vprint.cxx:85
bool ShowScrollbar(const tools::ULong aPage) const
Definition: PostItMgr.cxx:1941
bool HasNotes() const
Definition: PostItMgr.cxx:2116
bool ShowNotes() const
Definition: PostItMgr.cxx:2110
static Color GetColorAnchor(std::size_t aAuthorIndex)
Definition: PostItMgr.cxx:2185
Color GetArrowColor(sal_uInt16 aDirection, tools::ULong aPage) const
Definition: PostItMgr.cxx:1123
tools::ULong GetSidebarWidth(bool bPx=false) const
Definition: PostItMgr.cxx:2121
tools::ULong GetSidebarBorderWidth(bool bPx=false) const
Definition: PostItMgr.cxx:2147
sal_Int32 GetSidebarScrollerHeight() const
Definition: PostItMgr.cxx:2272
bool IsVert() const
Definition: frame.hxx:1372
void SetLeftAndWidth(SwRect &rRect, tools::Long nLeft, tools::Long nWidth) const
Definition: frame.hxx:1432
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1386
SwRectFn FnRect() const
Definition: frame.hxx:1374
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1384
tools::Long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1416
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:57
void Chg(const Point &rNP, const Size &rNS)
Definition: swrect.hxx:166
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool IsEmpty() const
Definition: swrect.hxx:304
tools::Long GetBottomDistance(tools::Long) const
Definition: swrect.cxx:138
bool HasArea() const
Definition: swrect.hxx:300
Point TopLeft() const
Definition: swrect.hxx:254
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
Point BottomLeft() const
Definition: swrect.hxx:262
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
tools::Long GetRightDistance(tools::Long) const
Definition: swrect.cxx:140
void Bottom_(const tools::Long nBottom)
Definition: swrect.cxx:114
SwRect & Intersection_(const SwRect &rRect)
Definition: swrect.cxx:81
void Pos(const Point &rNew)
Definition: swrect.hxx:171
void AddLeft(const tools::Long nAdd)
Definition: swrect.cxx:125
void SSize(const Size &rNew)
Definition: swrect.hxx:180
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
void AddBottom(const tools::Long nAdd)
Definition: swrect.cxx:130
tools::Long GetTopDistance(tools::Long) const
Definition: swrect.cxx:139
tools::Long GetLeftDistance(tools::Long) const
Definition: swrect.cxx:137
void AddRight(const tools::Long nAdd)
Definition: swrect.cxx:127
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:124
bool Overlaps(const SwRect &rRect) const
Definition: swrect.hxx:374
void AddTop(const tools::Long nAdd)
Definition: swrect.cxx:128
Point BottomRight() const
Definition: swrect.hxx:266
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:123
void Top_(const tools::Long nTop)
Definition: swrect.cxx:113
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Left_(const tools::Long nLeft)
Definition: swrect.cxx:111
void Right_(const tools::Long nRight)
Definition: swrect.cxx:112
Point TopRight() const
Definition: swrect.hxx:258
void Width(tools::Long nNew)
Definition: swrect.hxx:189
const SwRect & GetOrigin() const
Definition: swregion.hxx:62
The root element of a Writer document layout.
Definition: rootfrm.hxx:85
bool IsLeftToRightViewLayout() const
Definition: pagechg.cxx:2460
SwViewShell * mpCurrShell
Definition: rootfrm.hxx:169
void ResetTurboFlag() const
Definition: rootfrm.hxx:357
static bool s_isInPaint
Definition: rootfrm.hxx:108
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:215
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:434
bool IsCallbackActionEnabled() const
Definition: rootfrm.hxx:400
void SetCallbackActionEnabled(bool b)
Definition: rootfrm.hxx:399
void ResetTurbo()
Definition: rootfrm.hxx:360
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Paint once for every visible page which is touched by Rect.
Definition: paintfrm.cxx:3083
static bool s_isNoVirDev
Definition: rootfrm.hxx:109
static SwLayVout * s_pVout
Definition: rootfrm.hxx:107
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:29
bool IsRowSpanLine() const
Definition: rowfrm.hxx:105
const SwTableLine * GetTabLine() const
Definition: rowfrm.hxx:70
virtual void PaintSubsidiaryLines(const SwPageFrame *, const SwRect &) const override
Definition: paintfrm.cxx:7189
SectionType GetType() const
Definition: section.hxx:173
class for collecting anchored objects
Definition: sortedobjs.hxx:49
size_t size() const
Definition: sortedobjs.cxx:43
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:49
bool IsCollapsingBorders() const
Definition: tabfrm.cxx:6040
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:798
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:255
void ResetComplete()
Definition: tabfrm.hxx:167
const SwTable * GetTable() const
Definition: tabfrm.hxx:162
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: paintfrm.cxx:4450
sal_Int32 getRowSpan() const
Definition: swtable.hxx:540
SwTableLine * front() const
Definition: swtable.hxx:81
SwTableLines & GetTabLines()
Definition: swtable.hxx:206
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:201
bool IsNewModel() const
Definition: swtable.hxx:193
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
void PaintParagraphStylesHighlighting() const
Definition: paintfrm.cxx:4369
void UpdateOutlineContentVisibilityButton(SwWrtShell *pWrtSh) const
Definition: txtfrm.cxx:4200
static SwView * GetView()
Definition: paintfrm.cxx:4359
void PaintOutlineContentVisibilityButton() const
Definition: paintfrm.cxx:4443
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:472
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1390
sal_uInt16 GetBaseHeight() const
Definition: tgrditem.hxx:75
bool GetRubyTextBelow() const
Definition: tgrditem.hxx:85
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
bool GetPrintGrid() const
Definition: tgrditem.hxx:89
SwTextGrid GetGridType() const
Definition: tgrditem.hxx:81
bool GetDisplayGrid() const
Definition: tgrditem.hxx:93
const Color & GetColor() const
Definition: tgrditem.hxx:69
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:895
bool IsReadonly() const
Definition: viewopt.hxx:627
const Color & GetDocBoundariesColor() const
Definition: viewopt.cxx:457
const Color & GetShadowColor() const
Definition: viewopt.cxx:512
bool IsIndexShadings() const
Definition: viewopt.hxx:832
bool IsPagePreview() const
Definition: viewopt.hxx:799
const Color & GetFontColor() const
Definition: viewopt.cxx:517
const Color & GetIndexShadingsColor() const
Definition: viewopt.cxx:477
bool IsViewLayoutBookMode() const
Definition: viewopt.hxx:643
bool IsShowOutlineContentVisibilityButton() const
Definition: viewopt.cxx:177
bool IsShadow() const
Definition: viewopt.hxx:837
const Color & GetTextGridColor() const
Definition: viewopt.cxx:492
bool IsTable() const
Definition: viewopt.hxx:509
sal_uInt16 GetZoom() const
Definition: viewopt.hxx:669
static const SwViewOption & GetCurrentViewOptions()
Definition: viewopt.cxx:605
const Color & GetTableBoundariesColor() const
Definition: viewopt.cxx:472
bool IsPageBack() const
Definition: viewopt.hxx:504
bool getBrowseMode() const
Definition: viewopt.hxx:636
bool IsPDFExport() const
Definition: viewopt.hxx:588
bool IsGraphic() const
Definition: viewopt.hxx:499
static void DrawRect(OutputDevice *pOut, const SwRect &rRect, ::Color nCol)
Definition: viewopt.cxx:187
const Color & GetObjectBoundariesColor() const
Definition: viewopt.cxx:462
bool IsViewMetaChars() const
Definition: viewopt.hxx:546
bool IsFormView() const
Definition: viewopt.hxx:633
bool IsDocBoundaries() const
Definition: viewopt.hxx:829
const Color & GetSectionBoundColor() const
Definition: viewopt.cxx:527
Color GetRetoucheColor() const
Definition: viewimp.cxx:290
const SwPageFrame * GetFirstVisPage(OutputDevice const *pRenderContext) const
Management of the first visible Page.
Definition: viewimp.cxx:315
bool HasDrawView() const
New Interface for StarView Drawing.
Definition: viewimp.hxx:163
void DeletePaintRegion()
Definition: viewimp.hxx:157
SwDrawView * GetDrawView()
Definition: viewimp.hxx:164
SdrPageView * GetPageView()
Definition: viewimp.hxx:166
void PaintLayer(const SdrLayerID _nLayerID, SwPrintData const *const pPrintData, SwPageFrame const &rPageFrame, const SwRect &_rRect, const Color *_pPageBackgrdColor, const bool _bIsPageRightToLeft, sdr::contact::ViewObjectContactRedirector *pRedirector)
Definition: vdraw.cxx:88
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:365
VclPtr< vcl::Window > mpWin
= 0 during printing or pdf export
Definition: viewsh.hxx:141
void DLPrePaint2(const vcl::Region &rRegion)
Definition: viewsh.cxx:193
bool IsPreview() const
Definition: viewsh.hxx:517
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:452
VclPtr< OutputDevice > mpOut
Window, Printer, VirtDev, ...
Definition: viewsh.hxx:142
bool IsInEndAction() const
Definition: viewsh.hxx:226
void DLPostPaint2(bool bPaintFormLayer)
Definition: viewsh.cxx:232
const IDocumentDeviceAccess & getIDocumentDeviceAccess() const
Provides access to the document device interface.
Definition: viewsh.cxx:2819
SwViewShellImp * Imp()
Definition: viewsh.hxx:211
std::unique_ptr< SwViewOption > mpOpt
Definition: viewsh.hxx:144
bool ActionPend() const
Definition: viewsh.hxx:225
vcl::Window * GetWin() const
Definition: viewsh.hxx:364
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: viewsh.cxx:2823
const SwRect & VisArea() const
Definition: viewsh.cxx:642
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
const SwPostItMgr * GetPostItMgr() const
Definition: viewsh.hxx:583
static bool IsLstEndAction()
Definition: viewsh.hxx:369
const BitmapEx & GetReplacementBitmap(bool bIsErrorState)
Definition: viewsh.cxx:2747
Definition: view.hxx:146
SwEditWin & GetEditWin()
Definition: view.hxx:426
SwFlyFrame * GetFlyFrame()
Definition: dflyobj.hxx:135
virtual const tools::Rectangle & GetCurrentBoundRect() const override
Definition: dflyobj.cxx:569
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
const SwView & GetView() const
Definition: wrtsh.hxx:443
reference_type * get() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
B2DPoint getMaximum() const
B2DPoint getMinimum() const
TYPE getWidth() const
void expand(const Tuple2D< TYPE > &rTuple)
bool isEmpty() const
TYPE getHeight() const
TYPE getX() const
TYPE getY() const
TYPE getZ() const
void setZ(TYPE fZ)
void subtractRange(const B2DRange &)
B2DPolyPolygon const & getClipPoly() const
void setViewport(const basegfx::B2DRange &rNew)
void setViewTransformation(const basegfx::B2DHomMatrix &rNew)
void setVisualizedPage(const css::uno::Reference< css::drawing::XDrawPage > &rNew)
const BitmapEx & getBottomLeft() const
const BitmapEx & getBottomRight() const
const BitmapEx & getTopRight() const
void append(const Primitive2DReference &)
virtual SdrObject * TryToGetSdrObject() const
virtual void createRedirectedPrimitive2DSequence(const sdr::contact::ViewObjectContact &rOriginal, const sdr::contact::DisplayInfo &rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor)
ViewContact & GetViewContact() const
void SetType(SvxBorderLineStyle nType)
void Set(double nP, double nD, double nS)
Style & MirrorSelf()
virtual bool get(DocumentSettingId id) const override
Return the specified document setting.
ring_container GetRingContainer()
Definition: ring.hxx:240
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
::basegfx::B2DPolygon getB2DPolygon() const
void SetPoint(const Point &rPt, sal_uInt16 nPos)
constexpr tools::Long GetWidth() const
constexpr void SetLeft(tools::Long v)
bool Overlaps(const tools::Rectangle &rRect) const
constexpr void SetTop(tools::Long v)
tools::Rectangle GetIntersection(const tools::Rectangle &rRect) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr void SetRight(tools::Long v)
constexpr Size GetSize() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr void SetBottom(tools::Long v)
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
void expand(tools::Long nExpandBy)
static bool IsFuzzing()
void SetFontSize(const Size &)
void SetStyleName(const OUString &rStyleName)
void SetTransparent(bool bTransparent)
void SetColor(const Color &)
void SetWeight(FontWeight)
void SetFontHeight(tools::Long nHeight)
void SetFamily(FontFamily)
void SetUnderline(FontLineStyle)
void SetFamilyName(const OUString &rFamilyName)
void Exclude(const tools::Rectangle &rRegion)
Point LogicToPixel(const Point &rLogicPt) const
::OutputDevice const * GetOutDev() const
bool IsVisible() const
void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
constexpr ::Color COL_GRAY(0x80, 0x80, 0x80)
constexpr ::Color COL_AUTHOR_TABLE_DEL(0xFC, 0xE6, 0xF4)
constexpr ::Color COL_AUTHOR_TABLE_INS(0xE1, 0xF2, 0xFA)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
Color m_aColor
RedlineType
#define PROTOCOL(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:88
@ FileInit
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:172
struct _xmlTextWriter * xmlTextWriterPtr
virtual void Insert(SotClipboardFormatId nFormat, const OUString &rFormatName) override
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
aCursorMoveIdle Stop()
EmbeddedObjectRef * pObject
Any aHelper
DocumentType eType
@ COLADJ_BOTTOM
Definition: fmtclds.hxx:64
@ COLADJ_CENTER
Definition: fmtclds.hxx:63
@ COLADJ_NONE
Definition: fmtclds.hxx:61
@ COLADJ_TOP
Definition: fmtclds.hxx:62
FAMILY_SWISS
WEIGHT_BOLD
WEIGHT_NORMAL
SwRectFn fnRectVert
Definition: frame.hxx:1353
SwRectFn fnRectVertL2RB2T
Definition: frame.hxx:1353
SwRectFn fnRectHori
Definition: newfrm.cxx:287
SwRectFn fnRectVertL2R
Definition: frame.hxx:1353
#define GRFNUM_NO
Definition: frmtool.hxx:55
#define GRFNUM_REPLACE
Definition: frmtool.hxx:57
bool IsExtraData(const SwDoc *pDoc)
Definition: frmtool.cxx:3913
constexpr TypedWhichId< SwFormatURL > RES_URL(117)
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(111)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(162)
constexpr TypedWhichId< SfxBoolItem > RES_BACKGROUND_FULL_SIZE(138)
LanguageType GetAppLanguage()
Definition: init.cxx:741
constexpr sal_uInt16 KEY_PAGEDOWN
constexpr sal_uInt16 KEY_PAGEUP
sal_uInt16 nPos
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
bool equalZero(const T &rfVal)
const sal_uInt32 LEFT
const sal_uInt32 TOP
const sal_uInt32 BOTTOM
const sal_uInt32 RIGHT
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
bool isRectangle(const B2DPolygon &rPoly)
BColor rgb2hsl(const BColor &rRGBColor)
BColor hsl2rgb(const BColor &rHSLColor)
B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
B2DVector getNormalizedPerpendicular(const B2DVector &rVec)
std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr
Definition: format.hxx:41
std::vector< SdrFrameBorderData > SdrFrameBorderDataVector
attribute::FontAttribute getFontAttributeFromVclFont(basegfx::B2DVector &o_rSize, const vcl::Font &rFont, bool bRTL, bool bBiDiStrong)
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
int i
constexpr OUStringLiteral first
void DrawLine(OutputDevice &rDev, const Point &rP1, const Point &rP2, sal_uInt32 nWidth, SvxBorderLineStyle nDashing)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
Dialog to specify the properties of date form field.
Color * GetActiveRetoucheColor()
Definition: paintfrm.cxx:257
long Long
BitmapEx loadFromName(const OUString &rFileName, const ImageLoadFlags eFlags)
Graphic loadFromURL(OUString const &rURL, weld::Window *pParentWin)
::tools::Rectangle rectangleFromB2DRectangle(const basegfx::B2DRange &rRect)
HashMap_OWString_Interface aMap
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
SwNoteURL * pNoteURL
Definition: noteurl.cxx:23
void paintGraphicUsingPrimitivesHelper(vcl::RenderContext &rOutputDevice, GraphicObject const &rGrfObj, GraphicAttr const &rGraphicAttr, const basegfx::B2DHomMatrix &rGraphicTransform, const OUString &rName, const OUString &rTitle, const OUString &rDescription)
Definition: notxtfrm.cxx:915
const char GetValue[]
OUTDEV_WINDOW
OUTDEV_PRINTER
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2676
sal_uInt16 GetGridWidth(SwTextGridItem const &, SwDoc const &)
Definition: pagechg.cxx:2690
static bool lcl_compareFillAttributes(const drawinglayer::attribute::SdrAllFillAttributesHelperPtr &pA, const drawinglayer::attribute::SdrAllFillAttributesHelperPtr &pB)
Definition: paintfrm.cxx:6509
Color aGlobalRetoucheColor
Definition: paintfrm.cxx:253
static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(SwTabFrame const &rTabFrame, SwFrame const &rFrame, SvxBoxItem const &rBoxItem)
Special case: #i9860# first line in follow table without repeated headlines Special case: tdf#150308 ...
Definition: paintfrm.cxx:2812
static const SwFrame * lcl_GetCellFrameForBorderAttrs(const SwFrame *_pCellFrame, const SwBorderAttrs &_rCellBorderAttrs, const bool _bTop)
Determine cell frame, from which the border attributes for paint of top/bottom border has to be used.
Definition: paintfrm.cxx:5159
static bool isSubsidiaryLinesEnabled()
Definition: paintfrm.cxx:343
static void lclAddSubsidiaryLinesBounds(const std::vector< basegfx::B2DPolygon > &rPolygons, RectangleVector &rRects)
Definition: paintfrm.cxx:7111
#define BORDER_TILE_SIZE
Definition: paintfrm.cxx:6081
static bool isSubsidiaryLinesFlysEnabled()
Definition: paintfrm.cxx:335
static void lcl_SubtractFlys(const SwFrame *pFrame, const SwPageFrame *pPage, const SwRect &rRect, SwRegionRects &rRegion, basegfx::utils::B2DClipState &rClipState, SwPaintProperties const &rProperties)
Definition: paintfrm.cxx:1396
svx::frame::Style maStyleLeft
Definition: paintfrm.cxx:4800
static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateDashedIndicatorPrimitive(const basegfx::B2DPoint &rStart, const basegfx::B2DPoint &rEnd, basegfx::BColor aColor)
Definition: paintfrm.cxx:3647
static SwPaintProperties gProp
Definition: paintfrm.cxx:333
std::map< SwTwips, SwLineEntrySet > SwLineEntryMap
Definition: paintfrm.cxx:2386
static void lcl_AdjustRectToPixelSize(SwRect &io_aSwRect, const vcl::RenderContext &aOut)
Local helper for SwRootFrame::PaintSwFrame(..) - Adjust given rectangle to pixel size.
Definition: paintfrm.cxx:2163
static void lcl_EmergencyFormatFootnoteCont(SwFootnoteContFrame *pCont)
Definition: paintfrm.cxx:3447
static void lcl_implDrawGraphicBackground(const SvxBrushItem &_rBackgrdBrush, vcl::RenderContext &_rOut, const SwRect &_rAlignedPaintRect, const GraphicObject &_rGraphicObj, SwPaintProperties const &properties)
Definition: paintfrm.cxx:1561
static void lcl_DrawGraphic(const SvxBrushItem &rBrush, vcl::RenderContext &rOutDev, const SwViewShell &rSh, const SwRect &rGrf, const SwRect &rOut, bool bGrfNum, SwPaintProperties const &properties, bool bBackgrdAlreadyDrawn)
NNOTE: the transparency of the background graphic is saved in SvxBrushItem.GetGraphicObject(<shell>)....
Definition: paintfrm.cxx:1679
static const SwFrame * lcl_HasNextCell(const SwFrame &rFrame)
#i15844#
Definition: paintfrm.cxx:5120
basegfx::B2DHomMatrix maB2DHomMatrix
the transformation defining the geometry of this BorderRectangle
Definition: paintfrm.cxx:4794
const double aEdgeScale
Definition: paintfrm.cxx:250
static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateDelimiterPrimitives(const std::vector< basegfx::B2DPolygon > &rPolygons)
Definition: paintfrm.cxx:7002
static tools::Long lcl_AlignHeight(const tools::Long nHeight, SwPaintProperties const &properties)
Definition: paintfrm.cxx:1260
static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateColumnAreaDelimiterPrimitives(const SwRect &rRect)
Definition: paintfrm.cxx:7031
svx::frame::Style maStyleRight
Definition: paintfrm.cxx:4798
static bool isSubsidiaryLinesForSectionsEnabled()
Definition: paintfrm.cxx:352
void SwAlignGrfRect(SwRect *pGrfRect, const vcl::RenderContext &rOut)
Method to pixel-align rectangle for drawing graphic object.
Definition: paintfrm.cxx:1241
svx::frame::Style maStyleTop
the four styles to be used
Definition: paintfrm.cxx:4797
static std::vector< basegfx::B2DPolygon > lcl_CreatePageAreaDelimiterPolygons(const SwRect &rRect)
Definition: paintfrm.cxx:6973
void SetOutDevAndWin(SwViewShell *pSh, OutputDevice *pO, vcl::Window *pW, sal_uInt16 nZoom)
Definition: paintfrm.cxx:7810
bool DrawFillAttributes(const drawinglayer::attribute::SdrAllFillAttributesHelperPtr &rFillAttributes, const SwRect &rOriginalLayoutRect, const SwRegionRects &rPaintRegion, const basegfx::utils::B2DClipState &rClipState, vcl::RenderContext &rOut)
Definition: paintfrm.cxx:1734
static void lcl_ExtendLeftAndRight(SwRect &_rRect, const SwFrame &_rFrame, const SwBorderAttrs &_rAttrs, const SwRectFn &_rRectFn)
Extend left/right border/shadow rectangle to bottom of previous frame/to top of next frame,...
Definition: paintfrm.cxx:1364
static std::vector< basegfx::B2DPolygon > lcl_CreateRectangleDelimiterPolygons(const SwRect &rRect)
Definition: paintfrm.cxx:7014
svx::frame::Style maStyleBottom
Definition: paintfrm.cxx:4799
static void lcl_DrawDashedRect(OutputDevice *pOut, SwLineRect const &rLRect)
Definition: paintfrm.cxx:873
static void lcl_PaintShadow(const SwRect &rRect, SwRect &rOutRect, const SvxShadowItem &rShadow, const bool bDrawFullShadowRectangle, const bool bTop, const bool bBottom, const bool bLeft, const bool bRight, SwPaintProperties const &properties)
Paint border shadow.
Definition: paintfrm.cxx:4501
static void lcl_DrawGraphicBackground(const SvxBrushItem &_rBackgrdBrush, OutputDevice &_rOut, const SwRect &_rAlignedPaintRect, const GraphicObject &_rGraphicObj, bool _bNumberingGraphic, SwPaintProperties const &properties, bool _bBackgrdAlreadyDrawn=false)
This is a local help method to draw a background for a graphic.
Definition: paintfrm.cxx:1643
static void lcl_CalcBorderRect(SwRect &rRect, const SwFrame *pFrame, const SwBorderAttrs &rAttrs, const bool bShadow, SwPaintProperties const &properties)
Calculate PrtArea plus surrounding plus shadow.
Definition: paintfrm.cxx:1275
void SwAlignRect(SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext *pRenderContext)
Function <SwAlignRect(..)> is also used outside this file.
Definition: paintfrm.cxx:1135
static void lcl_paintBitmapExToRect(vcl::RenderContext *pOut, const Point &aPoint, const Size &aSize, const BitmapEx &rBitmapEx, PaintArea eArea)
Wrapper around pOut->DrawBitmapEx.
Definition: paintfrm.cxx:6084
std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet
Definition: paintfrm.cxx:2385
void PaintCharacterBorder(const SwFont &rFont, const SwRect &rPaintArea, const bool bVerticalLayout, const bool bVerticalLayoutLRBT, const bool bJoinWithPrev, const bool bJoinWithNext)
Paint border around a run of characters using frame painting code.
Definition: paintfrm.cxx:5040
static void lcl_RefreshLine(const SwLayoutFrame *pLay, const SwPageFrame *pPage, const Point &rP1, const Point &rP2, const SubColFlags nSubColor, SwLineRects *pSubsLines)
Subsidiary lines to paint the PrtAreas Only the LayoutFrames which directly contain Content Paints th...
Definition: paintfrm.cxx:6864
static basegfx::B2DRange lcl_ShrinkFly(const SwRect &rRect)
Returns a range suitable for subtraction when lcl_SubtractFlys() is used.
Definition: paintfrm.cxx:1383
static tools::Long lcl_AlignWidth(const tools::Long nWidth, SwPaintProperties const &properties)
Definition: paintfrm.cxx:1248
static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateRectangleDelimiterPrimitives(const SwRect &rRect)
Definition: paintfrm.cxx:7025
void DrawGraphic(const SvxBrushItem *pBrush, vcl::RenderContext &rOutDev, const SwRect &rOrg, const SwRect &rOut, const sal_uInt8 nGrfNum, const bool bConsiderBackgroundTransparency)
Definition: paintfrm.cxx:1823
void SwCalcPixStatics(vcl::RenderContext const *pOut)
Set borders alignment statics Adjustment for 'small' twip-to-pixel relations: For 'small' twip-to-pix...
Definition: paintfrm.cxx:388
#define Y
std::vector< tools::Rectangle > RectangleVector
Marks a position in the document model.
Definition: pam.hxx:38
SwFrameGet fnGetPrtTop
Definition: frame.hxx:1328
SwRectSet fnSetBottom
Definition: frame.hxx:1306
SwRectSet fnSetTop
Definition: frame.hxx:1305
SwRectSet fnSetWidth
Definition: frame.hxx:1309
SwRectGet fnGetLeft
Definition: frame.hxx:1298
SwRectSet fnSetPosX
Definition: frame.hxx:1319
SwFrameGet fnGetBottomMargin
Definition: frame.hxx:1323
SwFrameGet fnGetTopMargin
Definition: frame.hxx:1322
SwRectSet fnAddRight
Definition: frame.hxx:1315
SwRectSet fnSubTop
Definition: frame.hxx:1312
SwRectGet fnGetHeight
Definition: frame.hxx:1301
SwRectGet fnGetRight
Definition: frame.hxx:1299
SwRectSet fnAddBottom
Definition: frame.hxx:1313
SwFrameGet fnGetPrtBottom
Definition: frame.hxx:1329
SwRectSet fnSubLeft
Definition: frame.hxx:1314
UNDERLYING_TYPE get() const
#define PRIMITIVE2D_ID_SWBORDERRECTANGLERIMITIVE
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
#define SW_MOD()
Definition: swmodule.hxx:254
tools::Long(SwRect::* SwRectDist)(tools::Long) const
Definition: swrect.hxx:161
tools::Long(SwRect::* SwRectGet)() const
Definition: swrect.hxx:157
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
Size GetGraphicSizeTwip(const Graphic &rGraphic, vcl::RenderContext *pOutDev)
Definition: swtypes.cxx:28
tools::Long SwTwips
Definition: swtypes.hxx:51
SvxBoxItem & rBoxItem
@ GRID_LINES_CHARS
Definition: tgrditem.hxx:30
Left
Right
unsigned char sal_uInt8
signed char sal_Int8
SVXCORE_DLLPUBLIC css::uno::Reference< css::drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage) noexcept
Page
std::unordered_map< OUString, std::pair< Color, int > > StylesHighlighterColorMap
oslFileHandle & pOut
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)