LibreOffice Module sc (master) 1
output.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 <scitems.hxx>
21#include <editeng/brushitem.hxx>
22#include <svtools/colorcfg.hxx>
23#include <svx/rotmodit.hxx>
24#include <editeng/shaditem.hxx>
25#include <editeng/svxfont.hxx>
26#include <tools/poly.hxx>
27#include <vcl/svapp.hxx>
34#include <vcl/lineinfo.hxx>
35#include <vcl/gradient.hxx>
36#include <vcl/settings.hxx>
37#include <svx/unoapi.hxx>
38#include <sal/log.hxx>
39#include <comphelper/lok.hxx>
45
46#include <output.hxx>
47#include <document.hxx>
48#include <drwlayer.hxx>
49#include <formulacell.hxx>
50#include <attrib.hxx>
51#include <patattr.hxx>
52#include <progress.hxx>
53#include <pagedata.hxx>
54#include <chgtrack.hxx>
55#include <chgviset.hxx>
56#include <viewutil.hxx>
57#include <gridmerg.hxx>
58#include <fillinfo.hxx>
59#include <scmod.hxx>
60#include <appoptio.hxx>
61#include <postit.hxx>
62#include <validat.hxx>
63#include <detfunc.hxx>
64
65#include <SparklineRenderer.hxx>
66#include <colorscale.hxx>
67
68#include <math.h>
69#include <memory>
70
71using namespace com::sun::star;
72
73// Static Data
74
75// color for ChangeTracking "by author" as in the writer (swmodul1.cxx)
76
77#define SC_AUTHORCOLORCOUNT 9
78
83
84// Helper class for color assignment to avoid repeated lookups for the same user
85
87 rOpt( SC_MOD()->GetAppOptions() ),
88 rUsers( rTrack.GetUserCollection() ),
89 nLastUserIndex( 0 ),
90 nColor( COL_BLACK )
91{
92}
93
95{
96 Color nSetColor;
97 switch (rAction.GetType())
98 {
102 nSetColor = rOpt.GetTrackInsertColor();
103 break;
107 nSetColor = rOpt.GetTrackDeleteColor();
108 break;
109 case SC_CAT_MOVE:
110 nSetColor = rOpt.GetTrackMoveColor();
111 break;
112 default:
113 nSetColor = rOpt.GetTrackContentColor();
114 break;
115 }
116 if ( nSetColor != COL_TRANSPARENT ) // color assigned
117 nColor = nSetColor;
118 else // by author
119 {
120 if (aLastUserName != rAction.GetUser())
121 {
122 aLastUserName = rAction.GetUser();
123 std::set<OUString>::const_iterator it = rUsers.find(aLastUserName);
124 if (it == rUsers.end())
125 {
126 // empty string is possible if a name wasn't found while saving a 5.0 file
127 SAL_INFO_IF( aLastUserName.isEmpty(), "sc.ui", "Author not found" );
128 nLastUserIndex = 0;
129 }
130 else
131 {
132 size_t nPos = std::distance(rUsers.begin(), it);
134 }
135 }
137 }
138}
139
141 ScTableInfo& rTabInfo, ScDocument* pNewDoc,
142 SCTAB nNewTab, tools::Long nNewScrX, tools::Long nNewScrY,
143 SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
144 double nPixelPerTwipsX, double nPixelPerTwipsY,
145 const Fraction* pZoomX, const Fraction* pZoomY ) :
146 mpDev( pNewDev ),
147 mpRefDevice( pNewDev ), // default is output device
148 pFmtDevice( pNewDev ), // default is output device
149 mrTabInfo( rTabInfo ),
150 pRowInfo( rTabInfo.mpRowInfo.get() ),
151 nArrCount( rTabInfo.mnArrCount ),
152 mpDoc( pNewDoc ),
153 nTab( nNewTab ),
154 nScrX( nNewScrX ),
155 nScrY( nNewScrY ),
156 nX1( nNewX1 ),
157 nY1( nNewY1 ),
158 nX2( nNewX2 ),
159 nY2( nNewY2 ),
160 eType( eNewType ),
161 mnPPTX( nPixelPerTwipsX ),
162 mnPPTY( nPixelPerTwipsY ),
163 pViewShell( nullptr ),
164 pDrawView( nullptr ),
165 bEditMode( false ),
166 nEditCol( 0 ),
167 nEditRow( 0 ),
168 bMetaFile( false ),
169 bPagebreakMode( false ),
170 bSolidBackground( false ),
171 mbUseStyleColor( false ),
172 mbForceAutoColor( SvtAccessibilityOptions::GetIsAutomaticFontColor() ),
173 mbSyntaxMode( false ),
174 aGridColor( COL_BLACK ),
175 mbShowNullValues( true ),
176 mbShowFormulas( false ),
177 bShowSpellErrors( false ),
178 bMarkClipped( false ), // sal_False for printer/metafile etc.
179 bSnapPixel( false ),
180 bAnyClipped( false ),
181 bVertical(false),
182 mpTargetPaintWindow(nullptr), // #i74769# use SdrPaintWindow direct
183 mpSpellCheckCxt(nullptr)
184{
185 if (pZoomX)
186 aZoomX = *pZoomX;
187 else
188 aZoomX = Fraction(1,1);
189 if (pZoomY)
190 aZoomY = *pZoomY;
191 else
192 aZoomY = Fraction(1,1);
193
194 nVisX1 = nX1;
195 nVisY1 = nY1;
196 nVisX2 = nX2;
197 nVisY2 = nY2;
199
200 nScrW = 0;
201 for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
202 nScrW += pRowInfo[0].basicCellInfo(nX).nWidth;
203
204 nMirrorW = nScrW;
205
206 nScrH = 0;
207 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
208 nScrH += pRowInfo[nArrY].nHeight;
209
212
213 // always needed, so call at the end of the constructor
215}
216
218{
219}
220
222{
223 mpSpellCheckCxt = pCxt;
224}
225
227{
228 // use pContentDev instead of pDev where used
229
230 if ( mpRefDevice == mpDev )
231 mpRefDevice = pContentDev;
232 if ( pFmtDevice == mpDev )
233 pFmtDevice = pContentDev;
234 mpDev = pContentDev;
235}
236
238{
239 nMirrorW = nNew;
240}
241
243{
244 aGridColor = rColor;
245}
246
248{
249 bMarkClipped = bSet;
250}
251
253{
254 mbShowNullValues = bSet;
255}
256
258{
259 mbShowFormulas = bSet;
260}
261
263{
264 bShowSpellErrors = bSet;
265}
266
268{
269 bSnapPixel = true;
270}
271
273{
274 nEditCol = nCol;
275 nEditRow = nRow;
276 bEditMode = true;
277}
278
279void ScOutputData::SetMetaFileMode( bool bNewMode )
280{
281 bMetaFile = bNewMode;
282}
283
284void ScOutputData::SetSyntaxMode( bool bNewMode )
285{
286 mbSyntaxMode = bNewMode;
287 if ( bNewMode && !mxValueColor )
288 {
289 const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
293 }
294}
295
296void ScOutputData::DrawGrid(vcl::RenderContext& rRenderContext, bool bGrid, bool bPage, bool bMergeCover)
297{
298 // bMergeCover : Draw lines in sheet bgcolor to cover lok client grid lines in merged cell areas.
299 // When scNoGridBackground is set in lok mode, bMergeCover is set to true and bGrid to false.
300
301 SCCOL nX;
302 SCROW nY;
303 tools::Long nPosX;
304 tools::Long nPosY;
305 SCSIZE nArrY;
307 ScBreakType nBreakOld = ScBreakType::NONE;
308
309 bool bSingle;
310 bool bDashed = false;
311 Color aPageColor;
312 Color aManualColor;
313
314 if (bPagebreakMode)
315 bPage = false; // no "normal" breaks over the whole width/height
316
317 // It is a big mess to distinguish when we are using pixels and when logic
318 // units for drawing. Ultimately we want to work only in the logic units,
319 // but until that happens, we need to special-case:
320 //
321 // * metafile
322 // * drawing to the screen - everything is internally counted in pixels there
323 //
324 // 'Internally' in the above means the pCellInfo[...].nWidth and
325 // pRowInfo[...]->nHeight:
326 //
327 // * when bWorksInPixels is true: these are in pixels
328 // * when bWorksInPixels is false: these are in the logic units
329 //
330 // This is where all the confusion comes from, ultimately we want them
331 // always in the logic units (100th of millimeters), but we need to get
332 // there gradually (get rid of setting MapUnit::MapPixel first), otherwise we'd
333 // break all the drawing by one change.
334 // So until that happens, we need to special case.
335 bool bWorksInPixels = bMetaFile;
336 const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
337 Color aSheetBGColor = rColorCfg.GetColorValue(::svtools::DOCCOLOR).nColor;
338
339 if ( eType == OUTTYPE_WINDOW )
340 {
341 bWorksInPixels = true;
343 aManualColor = rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor;
344 }
345 else
346 {
347 aPageColor = aGridColor;
348 aManualColor = aGridColor;
349 }
350
351 tools::Long nOneX = 1;
352 tools::Long nOneY = 1;
353 if (!bWorksInPixels)
354 {
355 Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
356 nOneX = aOnePixel.Width();
357 nOneY = aOnePixel.Height();
358 }
359
360 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
361 tools::Long nSignedOneX = nOneX * nLayoutSign;
362
363 rRenderContext.SetLineColor(bMergeCover ? aSheetBGColor : aGridColor);
364
365 ScGridMerger aGrid(&rRenderContext, nOneX, nOneY);
366
367 // vertical lines
368
369 nPosX = nScrX;
370 if ( bLayoutRTL )
371 nPosX += nMirrorW - nOneX;
372
373 for (nX=nX1; nX<=nX2; nX++)
374 {
375 sal_uInt16 nWidth = pRowInfo[0].basicCellInfo(nX).nWidth;
376 if (nWidth)
377 {
378 nPosX += nWidth * nLayoutSign;
379
380 if ( bPage )
381 {
382 // Search also in hidden part for page breaks
383 SCCOL nCol = nX + 1;
384 while (nCol <= mpDoc->MaxCol())
385 {
386 nBreak = mpDoc->HasColBreak(nCol, nTab);
387 bool bHidden = mpDoc->ColHidden(nCol, nTab);
388
389 if ( nBreak != ScBreakType::NONE || !bHidden )
390 break;
391 ++nCol;
392 }
393
394 if (nBreak != nBreakOld)
395 {
396 aGrid.Flush();
397
398 if (static_cast<int>(nBreak))
399 {
400 rRenderContext.SetLineColor( (nBreak & ScBreakType::Manual) ? aManualColor :
401 aPageColor );
402 bDashed = true;
403 }
404 else
405 {
406 rRenderContext.SetLineColor(bMergeCover ? aSheetBGColor : aGridColor);
407 bDashed = false;
408 }
409
410 nBreakOld = nBreak;
411 }
412 }
413
414 bool bDraw = bGrid || nBreakOld != ScBreakType::NONE || bMergeCover; // simple grid only if set that way
415
416 sal_uInt16 nWidthXplus1 = pRowInfo[0].basicCellInfo(nX+1).nWidth;
417 bSingle = false;
418 if ( nX<mpDoc->MaxCol() && !bSingle )
419 {
420 bSingle = ( nWidthXplus1 == 0 );
421 for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
422 {
423 if (pRowInfo[nArrY].cellInfo(nX+1).bHOverlapped)
424 bSingle = true;
425 if (pRowInfo[nArrY].cellInfo(nX).bHideGrid)
426 bSingle = true;
427 }
428 }
429
430 if (bDraw)
431 {
432 if ( nX<mpDoc->MaxCol() && bSingle )
433 {
434 SCCOL nVisX = nX + 1;
435 while ( nVisX < mpDoc->MaxCol() && !mpDoc->GetColWidth(nVisX,nTab) )
436 ++nVisX;
437
438 nPosY = nScrY;
439 for (nArrY=1; nArrY+1<nArrCount; nArrY++)
440 {
441 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
442 const tools::Long nNextY = nPosY + pThisRowInfo->nHeight;
443
444 bool bHOver = pThisRowInfo->cellInfo(nX).bHideGrid;
445 if (!bHOver)
446 {
447 if (nWidthXplus1)
448 bHOver = pThisRowInfo->cellInfo(nX+1).bHOverlapped;
449 else
450 {
451 if (nVisX <= nX2)
452 bHOver = pThisRowInfo->cellInfo(nVisX).bHOverlapped;
453 else
454 bHOver = mpDoc->GetAttr(
455 nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG)
456 ->IsHorOverlapped();
457 if (bHOver)
458 bHOver = mpDoc->GetAttr(
459 nX + 1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG)
460 ->IsHorOverlapped();
461 }
462 }
463
464 if ((pThisRowInfo->bChanged && !bHOver && !bMergeCover) || (bHOver && bMergeCover))
465 {
466 aGrid.AddVerLine(bWorksInPixels, nPosX-nSignedOneX, nPosY, nNextY-nOneY, bDashed);
467 }
468 nPosY = nNextY;
469 }
470 }
471 else if (!bMergeCover)
472 {
473 aGrid.AddVerLine(bWorksInPixels, nPosX-nSignedOneX, nScrY, nScrY+nScrH-nOneY, bDashed);
474 }
475 }
476 }
477 }
478
479 // horizontal lines
480
481 bool bHiddenRow = true;
482 SCROW nHiddenEndRow = -1;
483 nPosY = nScrY;
484 for (nArrY=1; nArrY+1<nArrCount; nArrY++)
485 {
486 SCSIZE nArrYplus1 = nArrY+1;
487 nY = pRowInfo[nArrY].nRowNo;
488 SCROW nYplus1 = nY+1;
489 nPosY += pRowInfo[nArrY].nHeight;
490
491 if (pRowInfo[nArrY].bChanged)
492 {
493 if ( bPage )
494 {
495 for (SCROW i = nYplus1; i <= mpDoc->MaxRow(); ++i)
496 {
497 if (i > nHiddenEndRow)
498 bHiddenRow = mpDoc->RowHidden(i, nTab, nullptr, &nHiddenEndRow);
499 /* TODO: optimize the row break thing for large hidden
500 * segments where HasRowBreak() has to be called
501 * nevertheless for each row, as a row break is drawn also
502 * for hidden rows, above them. This needed to be done only
503 * once per hidden segment, maybe giving manual breaks
504 * priority. Something like GetNextRowBreak() and
505 * GetNextManualRowBreak(). */
506 nBreak = mpDoc->HasRowBreak(i, nTab);
507 if (!bHiddenRow || nBreak != ScBreakType::NONE)
508 break;
509 }
510
511 if (nBreakOld != nBreak)
512 {
513 aGrid.Flush();
514
515 if (static_cast<int>(nBreak))
516 {
517 rRenderContext.SetLineColor( (nBreak & ScBreakType::Manual) ? aManualColor :
518 aPageColor );
519 bDashed = true;
520 }
521 else
522 {
523 rRenderContext.SetLineColor(bMergeCover ? aSheetBGColor : aGridColor);
524 bDashed = false;
525 }
526
527 nBreakOld = nBreak;
528 }
529 }
530
531 bool bDraw = bGrid || nBreakOld != ScBreakType::NONE || bMergeCover; // simple grid only if set so
532
533 bool bNextYisNextRow = (pRowInfo[nArrYplus1].nRowNo == nYplus1);
534 bSingle = !bNextYisNextRow; // Hidden
535 for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
536 {
537 if (pRowInfo[nArrYplus1].cellInfo(i).bVOverlapped)
538 bSingle = true;
539 }
540
541 if (bDraw)
542 {
543 if ( bSingle && nY<mpDoc->MaxRow() )
544 {
545 SCROW nVisY = pRowInfo[nArrYplus1].nRowNo;
546
547 nPosX = nScrX;
548 if ( bLayoutRTL )
549 nPosX += nMirrorW - nOneX;
550
551 for (SCCOL i=nX1; i<=nX2; i++)
552 {
553 const tools::Long nNextX = nPosX + pRowInfo[0].basicCellInfo(i).nWidth * nLayoutSign;
554 if (nNextX != nPosX) // visible
555 {
556 bool bVOver;
557 if ( bNextYisNextRow )
558 bVOver = pRowInfo[nArrYplus1].cellInfo(i).bVOverlapped;
559 else
560 {
561 bVOver = mpDoc->GetAttr(
562 i,nYplus1,nTab,ATTR_MERGE_FLAG)
563 ->IsVerOverlapped()
564 && mpDoc->GetAttr(
565 i,nVisY,nTab,ATTR_MERGE_FLAG)
566 ->IsVerOverlapped();
568 }
569
570 if ((!bVOver && !bMergeCover) || (bVOver && bMergeCover))
571 {
572 aGrid.AddHorLine(bWorksInPixels, nPosX, nNextX-nSignedOneX, nPosY-nOneY, bDashed);
573 }
574 }
575 nPosX = nNextX;
576 }
577 }
578 else if (!bMergeCover)
579 {
580 aGrid.AddHorLine(bWorksInPixels, nScrX, nScrX+nScrW-nOneX, nPosY-nOneY, bDashed);
581 }
582 }
583 }
584 }
585}
586
588{
589 bPagebreakMode = true;
590 if (!pPageData)
591 return; // not yet initialized -> everything "not printed"
592
593 // mark printed range
594 // (everything in FillInfo is already initialized to sal_False)
595
596 sal_uInt16 nRangeCount = sal::static_int_cast<sal_uInt16>(pPageData->GetCount());
597 for (sal_uInt16 nPos=0; nPos<nRangeCount; nPos++)
598 {
599 ScRange aRange = pPageData->GetData( nPos ).GetPrintRange();
600
601 SCCOL nStartX = std::max( aRange.aStart.Col(), nX1 );
602 SCCOL nEndX = std::min( aRange.aEnd.Col(), nX2 );
603 SCROW nStartY = std::max( aRange.aStart.Row(), nY1 );
604 SCROW nEndY = std::min( aRange.aEnd.Row(), nY2 );
605
606 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
607 {
608 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
609 if ( pThisRowInfo->bChanged && pThisRowInfo->nRowNo >= nStartY &&
610 pThisRowInfo->nRowNo <= nEndY )
611 {
612 for (SCCOL nX=nStartX; nX<=nEndX; nX++)
613 pThisRowInfo->cellInfo(nX).bPrinted = true;
614 }
615 }
616 }
617}
618
620{
622 SCCOL nRotMax = nX2;
623 for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
624 if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
625 nRotMax = pRowInfo[nRotY].nRotMaxCol;
626
627 for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
628 {
629 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
630 if ( pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE &&
631 ( pThisRowInfo->bChanged || pRowInfo[nArrY-1].bChanged ||
632 ( nArrY+1<nArrCount && pRowInfo[nArrY+1].bChanged ) ) )
633 {
634 SCROW nY = pThisRowInfo->nRowNo;
635
636 for (SCCOL nX=0; nX<=nRotMax; nX++)
637 {
638 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
639 const ScPatternAttr* pPattern = pInfo->pPatternAttr;
640 const SfxItemSet* pCondSet = pInfo->pConditionSet;
641
642 if ( !pPattern && !mpDoc->ColHidden(nX, nTab) )
643 {
644 pPattern = mpDoc->GetPattern( nX, nY, nTab );
645 pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
646 }
647
648 if ( pPattern ) // column isn't hidden
649 {
650 ScRotateDir nDir = pPattern->GetRotateDir( pCondSet );
651 if (nDir != ScRotateDir::NONE)
652 {
653 // Needed for ScCellInfo internal decisions (bg fill, ...)
654 pInfo->nRotateDir = nDir;
655
656 // create target coordinates
657 const SCCOL nTargetX(nX - nVisX1 + 1);
658 const SCROW nTargetY(nY - nVisY1 + 1);
659
660 // Check for values - below in SetCellRotation these will
661 // be converted to size_t and thus may not be negative
662 if(nTargetX >= 0 && nTargetY >= 0)
663 {
664 // add rotation info to Array information
665 const Degree100 nAttrRotate(pPattern->GetRotateVal(pCondSet));
666 const SvxRotateMode eRotMode(pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet).GetValue());
667 const double fOrient((bLayoutRTL ? -1.0 : 1.0) * toRadians(nAttrRotate)); // 1/100th degrees -> [0..2PI]
669
670 rArray.SetCellRotation(nTargetX, nTargetY, eRotMode, fOrient);
671 }
672 }
673 }
674 }
675 }
676 }
677}
678
679static ScRotateDir lcl_GetRotateDir( const ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
680{
681 const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
682 const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
683
685
686 Degree100 nAttrRotate = pPattern->GetRotateVal( pCondSet );
687 if ( nAttrRotate )
688 {
689 SvxRotateMode eRotMode =
690 pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet).GetValue();
691
692 if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
694 else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
695 nRet = ScRotateDir::Center;
696 else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
697 {
698 tools::Long nRot180 = nAttrRotate.get() % 18000; // 1/100 degree
699 if ( nRot180 == 9000 )
700 nRet = ScRotateDir::Center;
701 else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
702 ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
703 nRet = ScRotateDir::Left;
704 else
705 nRet = ScRotateDir::Right;
706 }
707 }
708
709 return nRet;
710}
711
712static const SvxBrushItem* lcl_FindBackground( const ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
713{
714 const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
715 const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
716 const SvxBrushItem* pBackground =
717 &pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
718
719 ScRotateDir nDir = lcl_GetRotateDir( pDoc, nCol, nRow, nTab );
720
721 // treat CENTER like RIGHT
722 if ( nDir == ScRotateDir::Right || nDir == ScRotateDir::Center )
723 {
724 // text goes to the right -> take background from the left
725 while ( nCol > 0 && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
726 pBackground->GetColor().GetAlpha() != 0 )
727 {
728 --nCol;
729 pPattern = pDoc->GetPattern( nCol, nRow, nTab );
730 pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
731 pBackground = &pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
732 }
733 }
734 else if ( nDir == ScRotateDir::Left )
735 {
736 // text goes to the left -> take background from the right
737 while ( nCol < pDoc->MaxCol() && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
738 pBackground->GetColor().GetAlpha() != 0 )
739 {
740 ++nCol;
741 pPattern = pDoc->GetPattern( nCol, nRow, nTab );
742 pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
743 pBackground = &pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
744 }
745 }
746
747 return pBackground;
748}
749
750static bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
751 SCCOL nX1, SCCOL nX2, bool bShowProt, bool bPagebreakMode )
752{
753 if ( rFirst.bChanged != rOther.bChanged ||
754 rFirst.bEmptyBack != rOther.bEmptyBack )
755 return false;
756
757 SCCOL nX;
758 if ( bShowProt )
759 {
760 for ( nX=nX1; nX<=nX2; nX++ )
761 {
762 const ScPatternAttr* pPat1 = rFirst.cellInfo(nX).pPatternAttr;
763 const ScPatternAttr* pPat2 = rOther.cellInfo(nX).pPatternAttr;
764 if ( !pPat1 || !pPat2 ||
765 &pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) )
766 return false;
767 }
768 }
769 else
770 {
771 for ( nX=nX1; nX<=nX2; nX++ )
772 if ( rFirst.cellInfo(nX).pBackground != rOther.cellInfo(nX).pBackground )
773 return false;
774 }
775
776 if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != SC_ROTMAX_NONE )
777 for ( nX=nX1; nX<=nX2; nX++ )
778 if ( rFirst.cellInfo(nX).nRotateDir != rOther.cellInfo(nX).nRotateDir )
779 return false;
780
781 if ( bPagebreakMode )
782 for ( nX=nX1; nX<=nX2; nX++ )
783 if ( rFirst.cellInfo(nX).bPrinted != rOther.cellInfo(nX).bPrinted )
784 return false;
785
786 for ( nX=nX1; nX<=nX2; nX++ )
787 {
788 std::optional<Color> const & pCol1 = rFirst.cellInfo(nX).mxColorScale;
789 std::optional<Color> const & pCol2 = rOther.cellInfo(nX).mxColorScale;
790 if( (pCol1 && !pCol2) || (!pCol1 && pCol2) )
791 return false;
792
793 if (pCol1 && (*pCol1 != *pCol2))
794 return false;
795
796 const ScDataBarInfo* pInfo1 = rFirst.cellInfo(nX).pDataBar;
797 const ScDataBarInfo* pInfo2 = rOther.cellInfo(nX).pDataBar;
798
799 if( (pInfo1 && !pInfo2) || (!pInfo1 && pInfo2) )
800 return false;
801
802 if (pInfo1 && (*pInfo1 != *pInfo2))
803 return false;
804
805 // each cell with an icon set should be painted the same way
806 const ScIconSetInfo* pIconSet1 = rFirst.cellInfo(nX).pIconSet;
807 const ScIconSetInfo* pIconSet2 = rOther.cellInfo(nX).pIconSet;
808
809 if(pIconSet1 || pIconSet2)
810 return false;
811 }
812
813 return true;
814}
815
817{
818 if ( !bSolidBackground )
819 return;
820
821 Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
822 mpDev->SetLineColor(aBgColor);
823 mpDev->SetFillColor(aBgColor);
824
825 Point aScreenPos = mpDev->PixelToLogic(Point(nScrX, nScrY));
826 Size aScreenSize = mpDev->PixelToLogic(Size(nScrW - 1,nScrH - 1));
827
828 mpDev->DrawRect(tools::Rectangle(aScreenPos, aScreenSize));
829}
830
831namespace {
832
833const double lclCornerRectTransparency = 40.0;
834
835void drawDataBars(vcl::RenderContext& rRenderContext, const ScDataBarInfo* pOldDataBarInfo, const tools::Rectangle& rRect, tools::Long nOneX, tools::Long nOneY)
836{
837 tools::Long nPosZero = 0;
838 tools::Rectangle aPaintRect = rRect;
839 aPaintRect.AdjustTop(2 * nOneY );
840 aPaintRect.AdjustBottom( -(2 * nOneY) );
841 aPaintRect.AdjustLeft( 2 * nOneX );
842 aPaintRect.AdjustRight( -(2 * nOneX) );
843 if(pOldDataBarInfo->mnZero)
844 {
845 // need to calculate null point in cell
846 tools::Long nLength = aPaintRect.Right() - aPaintRect.Left();
847 nPosZero = static_cast<tools::Long>(aPaintRect.Left() + nLength*pOldDataBarInfo->mnZero/100.0);
848 }
849 else
850 {
851 nPosZero = aPaintRect.Left();
852 }
853
854 if(pOldDataBarInfo->mnLength < 0)
855 {
856 aPaintRect.SetRight( nPosZero );
857 tools::Long nLength = nPosZero - aPaintRect.Left();
858 aPaintRect.SetLeft( nPosZero + static_cast<tools::Long>(nLength * pOldDataBarInfo->mnLength/100.0) );
859 }
860 else if(pOldDataBarInfo->mnLength > 0)
861 {
862 aPaintRect.SetLeft( nPosZero );
863 tools::Long nLength = aPaintRect.Right() - nPosZero;
864 aPaintRect.SetRight( nPosZero + static_cast<tools::Long>(nLength * pOldDataBarInfo->mnLength/100.0) );
865 }
866 else
867 return;
868
869 if(pOldDataBarInfo->mbGradient)
870 {
871 rRenderContext.SetLineColor(pOldDataBarInfo->maColor);
872 Gradient aGradient(css::awt::GradientStyle_LINEAR, pOldDataBarInfo->maColor, COL_TRANSPARENT);
873 aGradient.SetSteps(255);
874
875 if(pOldDataBarInfo->mnLength < 0)
876 aGradient.SetAngle(2700_deg10);
877 else
878 aGradient.SetAngle(900_deg10);
879
880 rRenderContext.DrawGradient(aPaintRect, aGradient);
881
882 rRenderContext.SetLineColor();
883 }
884 else
885 {
886 rRenderContext.SetFillColor(pOldDataBarInfo->maColor);
887 rRenderContext.DrawRect(aPaintRect);
888 }
889
890 //draw axis
891 if(!(pOldDataBarInfo->mnZero && pOldDataBarInfo->mnZero != 100))
892 return;
893
894 Point aPoint1(nPosZero, rRect.Top());
895 Point aPoint2(nPosZero, rRect.Bottom());
896 LineInfo aLineInfo(LineStyle::Dash, 1);
897 aLineInfo.SetDashCount( 4 );
898 aLineInfo.SetDistance( 3 );
899 aLineInfo.SetDashLen( 3 );
900 rRenderContext.SetFillColor(pOldDataBarInfo->maAxisColor);
901 rRenderContext.SetLineColor(pOldDataBarInfo->maAxisColor);
902 rRenderContext.DrawLine(aPoint1, aPoint2, aLineInfo);
903 rRenderContext.SetLineColor();
904 rRenderContext.SetFillColor();
905}
906
907const BitmapEx& getIcon(sc::IconSetBitmapMap & rIconSetBitmapMap, ScIconSetType eType, sal_Int32 nIndex)
908{
909 return ScIconSetFormat::getBitmap(rIconSetBitmapMap, eType, nIndex);
910}
911
912void drawIconSets(vcl::RenderContext& rRenderContext, const ScIconSetInfo* pOldIconSetInfo, const tools::Rectangle& rRect, tools::Long nOneX, tools::Long nOneY,
913 sc::IconSetBitmapMap & rIconSetBitmapMap)
914{
915 ScIconSetType eType = pOldIconSetInfo->eIconSetType;
916 sal_Int32 nIndex = pOldIconSetInfo->nIconIndex;
917 const BitmapEx& rIcon = getIcon(rIconSetBitmapMap, eType, nIndex);
918
920
921 if (pOldIconSetInfo->mnHeight)
922 {
924 {
925 aHeight = rRenderContext.LogicToPixel(Size(0, pOldIconSetInfo->mnHeight), MapMode(MapUnit::MapTwip)).Height();
927 }
928 else
929 {
930 aHeight = o3tl::convert(pOldIconSetInfo->mnHeight, o3tl::Length::twip, o3tl::Length::mm100);
931 }
932 }
933
934 Size aSize = rIcon.GetSizePixel();
935 double fRatio = static_cast<double>(aSize.Width()) / aSize.Height();
936 tools::Long aWidth = fRatio * aHeight;
937
938 rRenderContext.Push();
939 rRenderContext.SetClipRegion(vcl::Region(rRect));
940 rRenderContext.DrawBitmapEx(Point(rRect.Left() + 2 * nOneX, rRect.Bottom() - 2 * nOneY - aHeight), Size(aWidth, aHeight), rIcon);
941 rRenderContext.Pop();
942}
943
944void drawCells(vcl::RenderContext& rRenderContext, std::optional<Color> const & pColor, const SvxBrushItem* pBackground, std::optional<Color>& pOldColor, const SvxBrushItem*& pOldBackground,
945 tools::Rectangle& rRect, tools::Long nPosX, tools::Long nLayoutSign, tools::Long nOneX, tools::Long nOneY, const ScDataBarInfo* pDataBarInfo, const ScDataBarInfo*& pOldDataBarInfo,
946 const ScIconSetInfo* pIconSetInfo, const ScIconSetInfo*& pOldIconSetInfo,
947 sc::IconSetBitmapMap & rIconSetBitmapMap)
948{
949 tools::Long nSignedOneX = nOneX * nLayoutSign;
950 // need to paint if old color scale has been used and now
951 // we have a different color or a style based background
952 // we can here fall back to pointer comparison
953 if (pOldColor && (pBackground || pOldColor != pColor || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo))
954 {
955 rRect.SetRight( nPosX-nSignedOneX );
956 if( !pOldColor->IsTransparent() )
957 {
958 rRenderContext.SetFillColor( *pOldColor );
959 rRenderContext.DrawRect( rRect );
960 }
961 if( pOldDataBarInfo )
962 drawDataBars(rRenderContext, pOldDataBarInfo, rRect, nOneX, nOneY);
963 if( pOldIconSetInfo )
964 drawIconSets(rRenderContext, pOldIconSetInfo, rRect, nOneX, nOneY, rIconSetBitmapMap);
965
966 rRect.SetLeft( nPosX - nSignedOneX );
967 }
968
969 if ( pOldBackground && (pColor ||pBackground != pOldBackground || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo) )
970 {
971 rRect.SetRight( nPosX-nSignedOneX );
972 if (pOldBackground) // ==0 if hidden
973 {
974 Color aBackCol = pOldBackground->GetColor();
975 if ( !aBackCol.IsTransparent() )
976 {
977 rRenderContext.SetFillColor( aBackCol );
978 rRenderContext.DrawRect( rRect );
979 }
980 }
981 if( pOldDataBarInfo )
982 drawDataBars(rRenderContext, pOldDataBarInfo, rRect, nOneX, nOneY);
983 if( pOldIconSetInfo )
984 drawIconSets(rRenderContext, pOldIconSetInfo, rRect, nOneX, nOneY, rIconSetBitmapMap);
985
986 rRect.SetLeft( nPosX - nSignedOneX );
987 }
988
989 if (!pOldBackground && !pOldColor && (pDataBarInfo || pIconSetInfo))
990 {
991 rRect.SetRight( nPosX -nSignedOneX );
992 rRect.SetLeft( nPosX - nSignedOneX );
993 }
994
995 if(pColor)
996 {
997 // only update pOldColor if the colors changed
998 if (!pOldColor || *pOldColor != *pColor)
999 pOldColor = pColor;
1000
1001 pOldBackground = nullptr;
1002 }
1003 else if(pBackground)
1004 {
1005 pOldBackground = pBackground;
1006 pOldColor.reset();
1007 }
1008
1009 if(pDataBarInfo)
1010 pOldDataBarInfo = pDataBarInfo;
1011 else
1012 pOldDataBarInfo = nullptr;
1013
1014 if(pIconSetInfo)
1015 pOldIconSetInfo = pIconSetInfo;
1016 else
1017 pOldIconSetInfo = nullptr;
1018}
1019
1020}
1021
1023{
1024 Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
1025 tools::Long nOneXLogic = aOnePixel.Width();
1026 tools::Long nOneYLogic = aOnePixel.Height();
1027
1028 // See more about bWorksInPixels in ScOutputData::DrawGrid
1029 bool bWorksInPixels = false;
1030 if (eType == OUTTYPE_WINDOW)
1031 bWorksInPixels = true;
1032
1033 tools::Long nOneX = 1;
1034 tools::Long nOneY = 1;
1035 if (!bWorksInPixels)
1036 {
1037 nOneX = nOneXLogic;
1038 nOneY = nOneYLogic;
1039 }
1040
1041 tools::Rectangle aRect;
1042
1043 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1044
1045 rRenderContext.SetLineColor();
1046
1047 bool bShowProt = mbSyntaxMode && mpDoc->IsTabProtected(nTab);
1048 bool bDoAll = bShowProt || bPagebreakMode || bSolidBackground;
1049
1050 bool bCellContrast = mbUseStyleColor &&
1052
1053 tools::Long nPosY = nScrY;
1054
1055 const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
1056 Color aProtectedColor( rColorCfg.GetColorValue( svtools::CALCPROTECTEDBACKGROUND ).nColor );
1057 auto pProtectedBackground = std::make_shared<SvxBrushItem>( aProtectedColor, ATTR_BACKGROUND );
1058
1059 // iterate through the rows to show
1060 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1061 {
1062 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1063 tools::Long nRowHeight = pThisRowInfo->nHeight;
1064
1065 if ( pThisRowInfo->bChanged )
1066 {
1067 if ( ( ( pThisRowInfo->bEmptyBack ) || mbSyntaxMode ) && !bDoAll )
1068 {
1069 // nothing
1070 }
1071 else
1072 {
1073 // scan for rows with the same background:
1074 SCSIZE nSkip = 0;
1075 while ( nArrY+nSkip+2<nArrCount &&
1076 lcl_EqualBack( *pThisRowInfo, pRowInfo[nArrY+nSkip+1],
1077 nX1, nX2, bShowProt, bPagebreakMode ) )
1078 {
1079 ++nSkip;
1080 nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
1081 }
1082
1083 tools::Long nPosX = nScrX;
1084
1085 if ( bLayoutRTL )
1086 nPosX += nMirrorW - nOneX;
1087
1088 aRect = tools::Rectangle(nPosX, nPosY - nOneY, nPosX, nPosY - nOneY + nRowHeight);
1089 if (bWorksInPixels)
1090 aRect = rRenderContext.PixelToLogic(aRect); // internal data in pixels, but we'll be drawing in logic units
1091
1092 const SvxBrushItem* pOldBackground = nullptr;
1093 const SvxBrushItem* pBackground = nullptr;
1094 std::optional<Color> pOldColor;
1095 const ScDataBarInfo* pOldDataBarInfo = nullptr;
1096 const ScIconSetInfo* pOldIconSetInfo = nullptr;
1097 SCCOL nMergedCols = 1;
1098 SCCOL nOldMerged = 0;
1099
1100 for (SCCOL nX=nX1; nX + nMergedCols <= nX2 + 1; nX += nOldMerged)
1101 {
1102 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX-1+nMergedCols);
1103
1104 nOldMerged = nMergedCols;
1105
1106 tools::Long nNewPosX = nPosX;
1107 // extend for all merged cells
1108 nMergedCols = 1;
1109 if (pInfo->bMerged && pInfo->pPatternAttr)
1110 {
1111 const ScMergeAttr* pMerge =
1113 nMergedCols = std::max<SCCOL>(1, pMerge->GetColMerge());
1114 }
1115
1116 for (SCCOL nMerged = 0; nMerged < nMergedCols; ++nMerged)
1117 {
1118 SCCOL nCol = nX+nOldMerged+nMerged;
1119 if (nCol > nX2+2)
1120 break;
1121 nNewPosX += pRowInfo[0].basicCellInfo(nCol-1).nWidth * nLayoutSign;
1122 }
1123
1124 if (nNewPosX == nPosX)
1125 continue; // Zero width, no need to draw.
1126
1127 if (bCellContrast)
1128 {
1129 // high contrast for cell borders and backgrounds -> empty background
1130 pBackground = ScGlobal::GetEmptyBrushItem();
1131 }
1132 else if (bShowProt) // show cell protection in syntax mode
1133 {
1134 const ScPatternAttr* pP = pInfo->pPatternAttr;
1135 if (pP)
1136 {
1137 const ScProtectionAttr& rProt = pP->GetItem(ATTR_PROTECTION);
1138 if (rProt.GetProtection() || rProt.GetHideCell())
1139 pBackground = pProtectedBackground.get();
1140 else
1141 pBackground = ScGlobal::GetEmptyBrushItem();
1142 }
1143 else
1144 pBackground = nullptr;
1145 }
1146 else
1147 pBackground = pInfo->pBackground;
1148
1149 if ( bPagebreakMode && !pInfo->bPrinted )
1150 pBackground = pProtectedBackground.get();
1151
1152 if ( pInfo->nRotateDir > ScRotateDir::Standard &&
1153 !pBackground->GetColor().IsFullyTransparent() &&
1154 !bCellContrast )
1155 {
1156 SCROW nY = pRowInfo[nArrY].nRowNo;
1157 pBackground = lcl_FindBackground( mpDoc, nX, nY, nTab );
1158 }
1159
1160 std::optional<Color> const & pColor = pInfo->mxColorScale;
1161 const ScDataBarInfo* pDataBarInfo = pInfo->pDataBar;
1162 const ScIconSetInfo* pIconSetInfo = pInfo->pIconSet;
1163
1164 tools::Long nPosXLogic = nPosX;
1165 if (bWorksInPixels)
1166 nPosXLogic = rRenderContext.PixelToLogic(Point(nPosX, 0)).X();
1167
1168 drawCells(rRenderContext, pColor, pBackground, pOldColor, pOldBackground, aRect, nPosXLogic, nLayoutSign, nOneXLogic, nOneYLogic, pDataBarInfo, pOldDataBarInfo, pIconSetInfo, pOldIconSetInfo, mpDoc->GetIconSetBitmapMap());
1169
1170 nPosX = nNewPosX;
1171 }
1172
1173 tools::Long nPosXLogic = nPosX;
1174 if (bWorksInPixels)
1175 nPosXLogic = rRenderContext.PixelToLogic(Point(nPosX, 0)).X();
1176
1177 drawCells(rRenderContext, std::optional<Color>(), nullptr, pOldColor, pOldBackground, aRect, nPosXLogic, nLayoutSign, nOneXLogic, nOneYLogic, nullptr, pOldDataBarInfo, nullptr, pOldIconSetInfo, mpDoc->GetIconSetBitmapMap());
1178
1179 nArrY += nSkip;
1180 }
1181 }
1182 nPosY += nRowHeight;
1183 }
1184}
1185
1187{
1188 DrawExtraShadow( false, false, false, false );
1189}
1190
1191void ScOutputData::DrawExtraShadow(bool bLeft, bool bTop, bool bRight, bool bBottom)
1192{
1193 mpDev->SetLineColor();
1194
1195 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1196 bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
1197 Color aAutoTextColor;
1198 if ( bCellContrast )
1199 aAutoTextColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
1200
1201 tools::Long nInitPosX = nScrX;
1202 if ( bLayoutRTL )
1203 {
1204 Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
1205 tools::Long nOneX = aOnePixel.Width();
1206 nInitPosX += nMirrorW - nOneX;
1207 }
1208 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1209
1210 tools::Long nPosY = nScrY - pRowInfo[0].nHeight;
1211 for (SCSIZE nArrY=0; nArrY<nArrCount; nArrY++)
1212 {
1213 bool bCornerY = ( nArrY == 0 ) || ( nArrY+1 == nArrCount );
1214 bool bSkipY = ( nArrY==0 && !bTop ) || ( nArrY+1 == nArrCount && !bBottom );
1215
1216 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1217 tools::Long nRowHeight = pThisRowInfo->nHeight;
1218
1219 if ( pThisRowInfo->bChanged && !bSkipY )
1220 {
1221 tools::Long nPosX = nInitPosX - pRowInfo[0].basicCellInfo(nX1-1).nWidth * nLayoutSign;
1222 for (SCCOL nCol=nX1-1; nCol<=nX2+1; nCol++)
1223 {
1224 bool bCornerX = ( nCol==nX1-1 || nCol==nX2+1 );
1225 bool bSkipX = ( nCol==nX1-1 && !bLeft ) || ( nCol==nX2+1 && !bRight );
1226
1227 for (sal_uInt16 nPass=0; nPass<2; nPass++) // horizontal / vertical
1228 {
1229 const SvxShadowItem* pAttr = nPass ?
1230 pThisRowInfo->cellInfo(nCol).pVShadowOrigin :
1231 pThisRowInfo->cellInfo(nCol).pHShadowOrigin;
1232 if ( pAttr && !bSkipX )
1233 {
1234 ScShadowPart ePart = nPass ?
1235 pThisRowInfo->cellInfo(nCol).eVShadowPart :
1236 pThisRowInfo->cellInfo(nCol).eHShadowPart;
1237
1238 bool bDo = true;
1239 if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
1240 if ( ePart != SC_SHADOW_CORNER )
1241 bDo = false;
1242
1243 if (bDo)
1244 {
1245 tools::Long nThisWidth = pRowInfo[0].basicCellInfo(nCol).nWidth;
1246 tools::Long nMaxWidth = nThisWidth;
1247 if (!nMaxWidth)
1248 {
1250 SCCOL nWx = nCol+1;
1251 while (nWx<nX2 && !pRowInfo[0].basicCellInfo(nWx).nWidth)
1252 ++nWx;
1253 nMaxWidth = pRowInfo[0].basicCellInfo(nWx).nWidth;
1254 }
1255
1256 // rectangle is in logical orientation
1257 tools::Rectangle aRect( nPosX, nPosY,
1258 nPosX + ( nThisWidth - 1 ) * nLayoutSign,
1259 nPosY + pRowInfo[nArrY].nHeight - 1 );
1260
1261 tools::Long nSize = pAttr->GetWidth();
1262 tools::Long nSizeX = static_cast<tools::Long>(nSize*mnPPTX);
1263 if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
1264 tools::Long nSizeY = static_cast<tools::Long>(nSize*mnPPTY);
1265 if (nSizeY >= nRowHeight) nSizeY = nRowHeight-1;
1266
1267 nSizeX *= nLayoutSign; // used only to add to rectangle values
1268
1269 SvxShadowLocation eLoc = pAttr->GetLocation();
1270 if ( bLayoutRTL )
1271 {
1272 // Shadow location is specified as "visual" (right is always right),
1273 // so the attribute's location value is mirrored here and in FillInfo.
1274 switch (eLoc)
1275 {
1276 case SvxShadowLocation::BottomRight: eLoc = SvxShadowLocation::BottomLeft; break;
1277 case SvxShadowLocation::BottomLeft: eLoc = SvxShadowLocation::BottomRight; break;
1278 case SvxShadowLocation::TopRight: eLoc = SvxShadowLocation::TopLeft; break;
1279 case SvxShadowLocation::TopLeft: eLoc = SvxShadowLocation::TopRight; break;
1280 default:
1281 {
1282 // added to avoid warnings
1283 }
1284 }
1285 }
1286
1287 if (ePart == SC_SHADOW_HORIZ || ePart == SC_SHADOW_HSTART ||
1288 ePart == SC_SHADOW_CORNER)
1289 {
1290 if (eLoc == SvxShadowLocation::TopLeft || eLoc == SvxShadowLocation::TopRight)
1291 aRect.SetTop( aRect.Bottom() - nSizeY );
1292 else
1293 aRect.SetBottom( aRect.Top() + nSizeY );
1294 }
1295 if (ePart == SC_SHADOW_VERT || ePart == SC_SHADOW_VSTART ||
1296 ePart == SC_SHADOW_CORNER)
1297 {
1298 if (eLoc == SvxShadowLocation::TopLeft || eLoc == SvxShadowLocation::BottomLeft)
1299 aRect.SetLeft( aRect.Right() - nSizeX );
1300 else
1301 aRect.SetRight( aRect.Left() + nSizeX );
1302 }
1303 if (ePart == SC_SHADOW_HSTART)
1304 {
1305 if (eLoc == SvxShadowLocation::TopLeft || eLoc == SvxShadowLocation::BottomLeft)
1306 aRect.AdjustRight( -nSizeX );
1307 else
1308 aRect.AdjustLeft(nSizeX );
1309 }
1310 if (ePart == SC_SHADOW_VSTART)
1311 {
1312 if (eLoc == SvxShadowLocation::TopLeft || eLoc == SvxShadowLocation::TopRight)
1313 aRect.AdjustBottom( -nSizeY );
1314 else
1315 aRect.AdjustTop(nSizeY );
1316 }
1317
1319 mpDev->SetFillColor( bCellContrast ? aAutoTextColor : pAttr->GetColor() );
1320 mpDev->DrawRect( aRect );
1321 }
1322 }
1323 }
1324
1325 nPosX += pRowInfo[0].basicCellInfo(nCol).nWidth * nLayoutSign;
1326 }
1327 }
1328 nPosY += nRowHeight;
1329 }
1330}
1331
1333{
1334 tools::Rectangle aRect;
1335 Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
1336 tools::Long nOneX = aOnePixel.Width();
1337 tools::Long nOneY = aOnePixel.Height();
1338
1339 // (called only for ScGridWindow)
1340 Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1341
1342 if (bMetaFile)
1343 nOneX = nOneY = 0;
1344
1345 mpDev->SetLineColor();
1346
1347 mpDev->SetFillColor( aBgColor );
1348
1349 tools::Long nPosY = nScrY;
1350 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1351 {
1352 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1353 tools::Long nRowHeight = pThisRowInfo->nHeight;
1354
1355 if ( pThisRowInfo->bChanged )
1356 {
1357 // scan for more rows which must be painted:
1358 SCSIZE nSkip = 0;
1359 while ( nArrY+nSkip+2<nArrCount && pRowInfo[nArrY+nSkip+1].bChanged )
1360 {
1361 ++nSkip;
1362 nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
1363 }
1364
1365 aRect = tools::Rectangle( Point( nScrX, nPosY ),
1366 Size( nScrW+1-nOneX, nRowHeight+1-nOneY) );
1367 mpDev->DrawRect( aRect );
1368
1369 nArrY += nSkip;
1370 }
1371 nPosY += nRowHeight;
1372 }
1373}
1374
1375// Lines
1376
1377static tools::Long lclGetSnappedX( const OutputDevice& rDev, tools::Long nPosX, bool bSnapPixel )
1378{
1379 return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
1380}
1381
1382static tools::Long lclGetSnappedY( const OutputDevice& rDev, tools::Long nPosY, bool bSnapPixel )
1383{
1384 return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 0, nPosY ) ) ).Height() : nPosY;
1385}
1386
1388{
1389 DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
1390
1391 Color aSingleColor;
1392 bool bUseSingleColor = false;
1393 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1394 bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
1395
1396 // if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
1397 // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
1398 // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
1399 // must be reset and the border colors handled here.
1400
1401 if ( ( nOldDrawMode & DrawModeFlags::WhiteFill ) && ( nOldDrawMode & DrawModeFlags::BlackLine ) )
1402 {
1403 rRenderContext.SetDrawMode( nOldDrawMode & (~DrawModeFlags::WhiteFill) );
1404 aSingleColor = COL_BLACK;
1405 bUseSingleColor = true;
1406 }
1407 else if ( ( nOldDrawMode & DrawModeFlags::SettingsFill ) && ( nOldDrawMode & DrawModeFlags::SettingsLine ) )
1408 {
1409 rRenderContext.SetDrawMode( nOldDrawMode & (~DrawModeFlags::SettingsFill) );
1410 aSingleColor = rStyleSettings.GetWindowTextColor(); // same as used in VCL for DrawModeFlags::SettingsLine
1411 bUseSingleColor = true;
1412 }
1413 else if ( bCellContrast )
1414 {
1415 aSingleColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
1416 bUseSingleColor = true;
1417 }
1418
1419 const Color* pForceColor = bUseSingleColor ? &aSingleColor : nullptr;
1420
1422 {
1423 DrawRotatedFrame(rRenderContext); // removes the lines that must not be painted here
1424 }
1425
1426 tools::Long nInitPosX = nScrX;
1427 if ( bLayoutRTL )
1428 {
1429 Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
1430 tools::Long nOneX = aOnePixel.Width();
1431 nInitPosX += nMirrorW - nOneX;
1432 }
1433 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1434
1435 // *** set column and row sizes of the frame border array ***
1436
1438 size_t nColCount = rArray.GetColCount();
1439 size_t nRowCount = rArray.GetRowCount();
1440
1441 // row heights
1442
1443 // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
1444 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
1445 tools::Long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
1446 tools::Long nOldSnapY = lclGetSnappedY( rRenderContext, nOldPosY, bSnapPixel );
1447 rArray.SetYOffset( nOldSnapY );
1448 for( size_t nRow = 0; nRow < nRowCount; ++nRow )
1449 {
1450 tools::Long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
1451 tools::Long nNewSnapY = lclGetSnappedY( rRenderContext, nNewPosY, bSnapPixel );
1452 rArray.SetRowHeight( nRow, nNewSnapY - nOldSnapY );
1453 nOldPosY = nNewPosY;
1454 nOldSnapY = nNewSnapY;
1455 }
1456
1457 // column widths
1458
1459 // column nX1-1 is not visible (dummy for borders from left) - subtract its width from initial position
1460 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
1461 tools::Long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].basicCellInfo( nX1 - 1 ).nWidth);
1462 tools::Long nOldSnapX = lclGetSnappedX( rRenderContext, nOldPosX, bSnapPixel );
1463 // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
1464 if( !bLayoutRTL )
1465 rArray.SetXOffset( nOldSnapX );
1466 for( SCCOL nCol = nX1 - 1; nCol <= nX2 + 1; ++nCol )
1467 {
1468 size_t nArrCol = bLayoutRTL ? nX2 + 1 - nCol : nCol - (nX1 - 1);
1469 tools::Long nNewPosX = nOldPosX + pRowInfo[ 0 ].basicCellInfo( nCol ).nWidth * nLayoutSign;
1470 tools::Long nNewSnapX = lclGetSnappedX( rRenderContext, nNewPosX, bSnapPixel );
1471 rArray.SetColWidth( nArrCol, std::abs( nNewSnapX - nOldSnapX ) );
1472 nOldPosX = nNewPosX;
1473 nOldSnapX = nNewSnapX;
1474 }
1475 if( bLayoutRTL )
1476 rArray.SetXOffset( nOldSnapX );
1477
1478 // *** draw the array ***
1479
1480 size_t nFirstCol = 1;
1481 size_t nFirstRow = 1;
1482 size_t nLastCol = nColCount - 2;
1483 size_t nLastRow = nRowCount - 2;
1484
1485 if( mrTabInfo.mbPageMode )
1486 rArray.SetClipRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
1487
1488 // draw only rows with set RowInfo::bChanged flag
1489 size_t nRow1 = nFirstRow;
1490 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(CreateProcessor2D());
1491 if (!pProcessor)
1492 return;
1493 while( nRow1 <= nLastRow )
1494 {
1495 while( (nRow1 <= nLastRow) && !pRowInfo[ nRow1 ].bChanged ) ++nRow1;
1496 if( nRow1 <= nLastRow )
1497 {
1498 size_t nRow2 = nRow1;
1499 while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
1500 auto xPrimitive = rArray.CreateB2DPrimitiveRange(
1501 nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
1502 pProcessor->process(xPrimitive);
1503 nRow1 = nRow2 + 1;
1504 }
1505 }
1506 pProcessor.reset();
1507
1508 rRenderContext.SetDrawMode(nOldDrawMode);
1509}
1510
1512{
1514 SCCOL nRotMax = nX2;
1515 for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
1516 if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
1517 nRotMax = pRowInfo[nRotY].nRotMaxCol;
1518
1519 const ScPatternAttr* pPattern;
1520 const SfxItemSet* pCondSet;
1521
1522 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1523 bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
1524
1525 tools::Long nInitPosX = nScrX;
1526 if ( bLayoutRTL )
1527 {
1528 Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
1529 tools::Long nOneX = aOnePixel.Width();
1530 nInitPosX += nMirrorW - nOneX;
1531 }
1532 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1533
1534 tools::Rectangle aClipRect( Point(nScrX, nScrY), Size(nScrW, nScrH) );
1535 if (bMetaFile)
1536 {
1537 rRenderContext.Push();
1538 rRenderContext.IntersectClipRegion( aClipRect );
1539 }
1540 else
1541 rRenderContext.SetClipRegion( vcl::Region( aClipRect ) );
1542
1543 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(CreateProcessor2D( ));
1544 tools::Long nPosY = nScrY;
1545 for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
1546 {
1547 // Rotated is also drawn one line above/below Changed if parts extend into the cell
1548
1549 RowInfo& rPrevRowInfo = pRowInfo[nArrY-1];
1550 RowInfo& rThisRowInfo = pRowInfo[nArrY];
1551 RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
1552
1553 tools::Long nRowHeight = rThisRowInfo.nHeight;
1554 if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
1555 ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
1556 ( nArrY+1<nArrCount && rNextRowInfo.bChanged ) ) )
1557 {
1558 SCROW nY = rThisRowInfo.nRowNo;
1559 tools::Long nPosX = 0;
1560 SCCOL nX;
1561 for (nX=0; nX<=nRotMax; nX++)
1562 {
1563 if (nX==nX1) nPosX = nInitPosX; // calculated individually for preceding positions
1564
1565 ScCellInfo* pInfo = &rThisRowInfo.cellInfo(nX);
1566 tools::Long nColWidth = pRowInfo[0].basicCellInfo(nX).nWidth;
1567 if ( pInfo->nRotateDir > ScRotateDir::Standard &&
1568 !pInfo->bHOverlapped && !pInfo->bVOverlapped )
1569 {
1570 pPattern = pInfo->pPatternAttr;
1571 pCondSet = pInfo->pConditionSet;
1572 if (!pPattern)
1573 {
1574 pPattern = mpDoc->GetPattern( nX, nY, nTab );
1575 pInfo->pPatternAttr = pPattern;
1576 pCondSet = mpDoc->GetCondResult( nX, nY, nTab );
1577 pInfo->pConditionSet = pCondSet;
1578 }
1579
1581
1582 Degree100 nAttrRotate = pPattern->GetRotateVal( pCondSet );
1583 SvxRotateMode eRotMode =
1584 pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet).GetValue();
1585
1586 if (nAttrRotate)
1587 {
1588 if (nX < nX1) // compute negative position
1589 {
1590 nPosX = nInitPosX;
1591 SCCOL nCol = nX1;
1592 while (nCol > nX)
1593 {
1594 --nCol;
1595 nPosX -= nLayoutSign * static_cast<tools::Long>(pRowInfo[0].basicCellInfo(nCol).nWidth);
1596 }
1597 }
1598
1599 // start position minus 1 so rotated backgrounds suit the border
1600 // (border is on the grid)
1601
1602 tools::Long nTop = nPosY - 1;
1603 tools::Long nBottom = nPosY + nRowHeight - 1;
1604 tools::Long nTopLeft = nPosX - nLayoutSign;
1605 tools::Long nTopRight = nPosX + (nColWidth - 1) * nLayoutSign;
1606 tools::Long nBotLeft = nTopLeft;
1607 tools::Long nBotRight = nTopRight;
1608
1609 // inclusion of the sign here hasn't been decided yet
1610 // (if not, the extension of the non-rotated background must also be changed)
1611 double nRealOrient = nLayoutSign * toRadians(nAttrRotate); // 1/100th degrees
1612 double nCos = cos(nRealOrient);
1613 double nSin = sin(nRealOrient);
1615 tools::Long nSkew = static_cast<tools::Long>(nRowHeight * nCos / nSin);
1616
1617 switch (eRotMode)
1618 {
1620 nTopLeft += nSkew;
1621 nTopRight += nSkew;
1622 break;
1624 nSkew /= 2;
1625 nTopLeft += nSkew;
1626 nTopRight += nSkew;
1627 nBotLeft -= nSkew;
1628 nBotRight -= nSkew;
1629 break;
1631 nBotLeft -= nSkew;
1632 nBotRight -= nSkew;
1633 break;
1634 default:
1635 {
1636 // added to avoid warnings
1637 }
1638 }
1639
1640 Point aPoints[4];
1641 aPoints[0] = Point(nTopLeft, nTop);
1642 aPoints[1] = Point(nTopRight, nTop);
1643 aPoints[2] = Point(nBotRight, nBottom);
1644 aPoints[3] = Point(nBotLeft, nBottom);
1645
1646 const SvxBrushItem* pBackground = pInfo->pBackground;
1647 if (!pBackground)
1648 pBackground = &pPattern->GetItem(ATTR_BACKGROUND, pCondSet);
1649 if (bCellContrast)
1650 {
1651 // high contrast for cell borders and backgrounds -> empty background
1652 pBackground = ScGlobal::GetEmptyBrushItem();
1653 }
1654 if (!pInfo->mxColorScale)
1655 {
1656 const Color& rColor = pBackground->GetColor();
1657 if (rColor.GetAlpha() != 0)
1658 {
1659 // draw background only for the changed row itself
1660 // (background doesn't extend into other cells).
1661 // For the borders (rotated and normal), clipping should be
1662 // set if the row isn't changed, but at least the borders
1663 // don't cover the cell contents.
1664 if (rThisRowInfo.bChanged)
1665 {
1666 tools::Polygon aPoly(4, aPoints);
1667
1668 // for DrawPolygon, without Pen one pixel is left out
1669 // to the right and below...
1670 if (!rColor.IsTransparent())
1671 rRenderContext.SetLineColor(rColor);
1672 else
1673 rRenderContext.SetLineColor();
1674 rRenderContext.SetFillColor(rColor);
1675 rRenderContext.DrawPolygon(aPoly);
1676 }
1677 }
1678 }
1679 else
1680 {
1681 tools::Polygon aPoly(4, aPoints);
1682 std::optional<Color> const & pColor = pInfo->mxColorScale;
1683
1684 // for DrawPolygon, without Pen one pixel is left out
1685 // to the right and below...
1686 if (!pColor->IsTransparent())
1687 rRenderContext.SetLineColor(*pColor);
1688 else
1689 rRenderContext.SetLineColor();
1690 rRenderContext.SetFillColor(*pColor);
1691 rRenderContext.DrawPolygon(aPoly);
1692
1693 }
1694 }
1695 }
1696 nPosX += nColWidth * nLayoutSign;
1697 }
1698 }
1699 nPosY += nRowHeight;
1700 }
1701
1702 pProcessor.reset();
1703
1704 if (bMetaFile)
1705 rRenderContext.Pop();
1706 else
1707 rRenderContext.SetClipRegion();
1708}
1709
1710std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> ScOutputData::CreateProcessor2D( )
1711{
1713 ScDrawLayer* pDrawLayer = mpDoc->GetDrawLayer();
1714 if (!pDrawLayer)
1715 return nullptr;
1716
1717 basegfx::B2DRange aViewRange;
1718 SdrPage *pDrawPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( nTab ) );
1720 aNewViewInfos.setViewTransformation(mpDev->GetViewTransformation());
1721 aNewViewInfos.setViewport(aViewRange);
1722 aNewViewInfos.setVisualizedPage(GetXDrawPageForSdrPage( pDrawPage ));
1723
1725 *mpDev, aNewViewInfos );
1726}
1727
1728// Printer
1729
1731{
1732 vcl::Region aRegion;
1733 tools::Rectangle aDrawingRect;
1734 bool bHad(false);
1735 tools::Long nPosY = nScrY;
1736 SCSIZE nArrY;
1737
1738 aDrawingRect.SetLeft( nScrX );
1739 aDrawingRect.SetRight( nScrX+nScrW-1 );
1740
1741 for(nArrY=1; nArrY+1<nArrCount; nArrY++)
1742 {
1743 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1744
1745 if(pThisRowInfo->bChanged)
1746 {
1747 if(!bHad)
1748 {
1749 aDrawingRect.SetTop( nPosY );
1750 bHad = true;
1751 }
1752
1753 aDrawingRect.SetBottom( nPosY + pRowInfo[nArrY].nHeight - 1 );
1754 }
1755 else if(bHad)
1756 {
1757 aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
1758 bHad = false;
1759 }
1760
1761 nPosY += pRowInfo[nArrY].nHeight;
1762 }
1763
1764 if(bHad)
1765 {
1766 aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
1767 }
1768
1769 return aRegion;
1770}
1771
1773{
1774 tools::PolyPolygon aPoly;
1775
1776 tools::Rectangle aDrawingRect;
1777 aDrawingRect.SetLeft( nScrX );
1778 aDrawingRect.SetRight( nScrX+nScrW-1 );
1779
1780 bool bHad = false;
1781 tools::Long nPosY = nScrY;
1782 SCSIZE nArrY;
1783 for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1784 {
1785 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1786
1787 if ( pThisRowInfo->bChanged )
1788 {
1789 if (!bHad)
1790 {
1791 aDrawingRect.SetTop( nPosY );
1792 bHad = true;
1793 }
1794 aDrawingRect.SetBottom( nPosY + pRowInfo[nArrY].nHeight - 1 );
1795 }
1796 else if (bHad)
1797 {
1798 aPoly.Insert( tools::Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
1799 bHad = false;
1800 }
1801 nPosY += pRowInfo[nArrY].nHeight;
1802 }
1803
1804 if (bHad)
1805 aPoly.Insert( tools::Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
1806
1807 bool bRet = (aPoly.Count() != 0);
1808 if (bRet)
1809 mpDev->SetClipRegion(vcl::Region(aPoly));
1810 return bRet;
1811}
1812
1814{
1815 SCCOL nX;
1816 SCSIZE nArrY;
1817
1818 bool bWasIdleEnabled = mpDoc->IsIdleEnabled();
1819 mpDoc->EnableIdle(false);
1820 for (nArrY=0; nArrY<nArrCount; nArrY++)
1821 pRowInfo[nArrY].bChanged = false;
1822
1823 SCCOL nCol1 = mpDoc->MaxCol(), nCol2 = 0;
1824 SCROW nRow1 = mpDoc->MaxRow(), nRow2 = 0;
1825 bool bAnyDirty = false;
1826 bool bAnyChanged = false;
1827
1828 for (nArrY=0; nArrY<nArrCount; nArrY++)
1829 {
1830 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1831 for (nX=nX1; nX<=nX2; nX++)
1832 {
1833 const ScRefCellValue& rCell = pThisRowInfo->cellInfo(nX).maCell;
1834
1835 if (rCell.getType() != CELLTYPE_FORMULA)
1836 continue;
1837
1838 ScFormulaCell* pFCell = rCell.getFormula();
1839 if (pFCell->IsRunning())
1840 // still being interpreted. Skip it.
1841 continue;
1842
1843 bool bDirty = pFCell->GetDirty();
1844 bAnyChanged = bAnyChanged || pFCell->IsChanged();
1845
1846 if (bDirty)
1847 {
1848 if (!bAnyDirty)
1849 {
1851 bAnyDirty = true;
1852 }
1853
1854 ScAddress& rPos(pFCell->aPos);
1855 nCol1 = std::min(rPos.Col(), nCol1);
1856 nCol2 = std::max(rPos.Col(), nCol2);
1857 nRow1 = std::min(rPos.Row(), nRow1);
1858 nRow2 = std::max(rPos.Row(), nRow2);
1859
1860 const SfxUInt32Item* pItem = mpDoc->GetAttr(rPos, ATTR_VALIDDATA);
1862 if (pData)
1863 {
1864 ScRefCellValue aCell(*mpDoc, rPos);
1865 if (pData->IsDataValid(aCell, rPos))
1866 ScDetectiveFunc(*mpDoc, rPos.Tab()).DeleteCirclesAt(rPos.Col(), rPos.Row());
1867 }
1868 }
1869 }
1870 }
1871
1872 if (bAnyDirty || bAnyChanged)
1873 {
1874 if (bAnyDirty)
1875 mpDoc->EnsureFormulaCellResults(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab), true);
1876
1877 for (nArrY=0; nArrY<nArrCount; nArrY++)
1878 {
1879 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1880 for (nX=nX1; nX<=nX2; nX++)
1881 {
1882 const ScRefCellValue& rCell = pThisRowInfo->cellInfo(nX).maCell;
1883
1884 if (rCell.getType() != CELLTYPE_FORMULA)
1885 continue;
1886
1887 ScFormulaCell* pFCell = rCell.getFormula();
1888 if (pFCell->IsRunning())
1889 // still being interpreted. Skip it.
1890 continue;
1891
1892 if (!pFCell->IsChanged())
1893 // the result hasn't changed. Skip it.
1894 continue;
1895
1896 pThisRowInfo->bChanged = true;
1897 if ( pThisRowInfo->cellInfo(nX).bMerged )
1898 {
1899 SCSIZE nOverY = nArrY + 1;
1900 while ( nOverY<nArrCount &&
1901 pRowInfo[nOverY].cellInfo(nX).bVOverlapped )
1902 {
1903 pRowInfo[nOverY].bChanged = true;
1904 ++nOverY;
1905 }
1906 }
1907 }
1908 }
1909
1910 if (bAnyDirty)
1912 }
1913
1914 mpDoc->EnableIdle(bWasIdleEnabled);
1915}
1916
1918 SCCOL nRefEndX, SCROW nRefEndY, const Color& rColor)
1919{
1920 ReferenceMark aResult;
1921
1922 PutInOrder( nRefStartX, nRefEndX );
1923 PutInOrder( nRefStartY, nRefEndY );
1924
1925 if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
1926 mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
1927
1928 if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
1929 nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
1930 {
1931 tools::Long nMinX = nScrX;
1932 tools::Long nMinY = nScrY;
1933 tools::Long nMaxX = nScrX + nScrW - 1;
1934 tools::Long nMaxY = nScrY + nScrH - 1;
1935 if ( bLayoutRTL )
1936 std::swap( nMinX, nMaxX );
1937 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1938
1939 bool bTop = false;
1940 bool bBottom = false;
1941 bool bLeft = false;
1942 bool bRight = false;
1943
1944 tools::Long nPosY = nScrY;
1945 bool bNoStartY = ( nY1 < nRefStartY );
1946 bool bNoEndY = false;
1947 for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
1948 {
1949 SCROW nY = pRowInfo[nArrY].nRowNo;
1950
1951 if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
1952 {
1953 nMinY = nPosY;
1954 bTop = true;
1955 }
1956 if ( nY==nRefEndY )
1957 {
1958 nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
1959 bBottom = true;
1960 }
1961 if ( nY>nRefEndY && bNoEndY )
1962 {
1963 nMaxY = nPosY-2;
1964 bBottom = true;
1965 }
1966 bNoStartY = ( nY < nRefStartY );
1967 bNoEndY = ( nY < nRefEndY );
1968 nPosY += pRowInfo[nArrY].nHeight;
1969 }
1970
1971 tools::Long nPosX = nScrX;
1972 if ( bLayoutRTL )
1973 nPosX += nMirrorW - 1; // always in pixels
1974
1975 for (SCCOL nX=nX1; nX<=nX2; nX++)
1976 {
1977 if ( nX==nRefStartX )
1978 {
1979 nMinX = nPosX;
1980 bLeft = true;
1981 }
1982 if ( nX==nRefEndX )
1983 {
1984 nMaxX = nPosX + ( pRowInfo[0].basicCellInfo(nX).nWidth - 2 ) * nLayoutSign;
1985 bRight = true;
1986 }
1987 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
1988 }
1989
1990 if (bTop && bBottom && bLeft && bRight)
1991 {
1992 // mnPPT[XY] already has the factor aZoom[XY] in it.
1993 aResult = ReferenceMark( nMinX / mnPPTX,
1994 nMinY / mnPPTY,
1995 ( nMaxX - nMinX ) / mnPPTX,
1996 ( nMaxY - nMinY ) / mnPPTY,
1997 nTab,
1998 rColor );
1999 }
2000 }
2001
2002 return aResult;
2003}
2004
2005void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
2006 SCCOL nRefEndX, SCROW nRefEndY,
2007 const Color& rColor, bool bHandle )
2008{
2009 PutInOrder( nRefStartX, nRefEndX );
2010 PutInOrder( nRefStartY, nRefEndY );
2011
2012 if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
2013 mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
2014
2015 if ( !(nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
2016 nRefStartY <= nVisY2 && nRefEndY >= nVisY1) )
2017 return;
2018
2019 tools::Long nMinX = nScrX;
2020 tools::Long nMinY = nScrY;
2021 tools::Long nMaxX = nScrX + nScrW - 1;
2022 tools::Long nMaxY = nScrY + nScrH - 1;
2023 if ( bLayoutRTL )
2024 std::swap( nMinX, nMaxX );
2025 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2026
2027 bool bTop = false;
2028 bool bBottom = false;
2029 bool bLeft = false;
2030 bool bRight = false;
2031
2032 tools::Long nPosY = nScrY;
2033 bool bNoStartY = ( nY1 < nRefStartY );
2034 bool bNoEndY = false;
2035 for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
2036 {
2037 SCROW nY = pRowInfo[nArrY].nRowNo;
2038
2039 if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2040 {
2041 nMinY = nPosY;
2042 bTop = true;
2043 }
2044 if ( nY==nRefEndY )
2045 {
2046 nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
2047 bBottom = true;
2048 }
2049 if ( nY>nRefEndY && bNoEndY )
2050 {
2051 nMaxY = nPosY-2;
2052 bBottom = true;
2053 }
2054 bNoStartY = ( nY < nRefStartY );
2055 bNoEndY = ( nY < nRefEndY );
2056 nPosY += pRowInfo[nArrY].nHeight;
2057 }
2058
2059 tools::Long nPosX = nScrX;
2060 if ( bLayoutRTL )
2061 nPosX += nMirrorW - 1; // always in pixels
2062
2063 for (SCCOL nX=nX1; nX<=nX2; nX++)
2064 {
2065 if ( nX==nRefStartX )
2066 {
2067 nMinX = nPosX;
2068 bLeft = true;
2069 }
2070 if ( nX==nRefEndX )
2071 {
2072 nMaxX = nPosX + ( pRowInfo[0].basicCellInfo(nX).nWidth - 2 ) * nLayoutSign;
2073 bRight = true;
2074 }
2075 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2076 }
2077
2078 if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
2079 return;
2080
2081 mpDev->SetLineColor( rColor );
2082 if (bTop && bBottom && bLeft && bRight && !comphelper::LibreOfficeKit::isActive() )
2083 {
2084 mpDev->SetFillColor();
2085 mpDev->DrawRect( tools::Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2086 }
2088 {
2089 if (bTop)
2090 mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMaxX, nMinY ) );
2091 if (bBottom)
2092 mpDev->DrawLine( Point( nMinX, nMaxY ), Point( nMaxX, nMaxY ) );
2093 if (bLeft)
2094 mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMinX, nMaxY ) );
2095 if (bRight)
2096 mpDev->DrawLine( Point( nMaxX, nMinY ), Point( nMaxX, nMaxY ) );
2097 }
2098 if ( !bHandle || !bRight || !bBottom || comphelper::LibreOfficeKit::isActive() )
2099 return;
2100
2101 mpDev->SetLineColor( rColor );
2102 mpDev->SetFillColor( rColor );
2103
2104 const sal_Int32 aRadius = 4;
2105
2106 sal_Int32 aRectMaxX1 = nMaxX - nLayoutSign * aRadius;
2107 sal_Int32 aRectMaxX2 = nMaxX + nLayoutSign;
2108 sal_Int32 aRectMinX1 = nMinX - nLayoutSign;
2109 sal_Int32 aRectMinX2 = nMinX + nLayoutSign * aRadius;
2110
2111 sal_Int32 aRectMaxY1 = nMaxY - aRadius;
2112 sal_Int32 aRectMaxY2 = nMaxY + 1;
2113 sal_Int32 aRectMinY1 = nMinY - 1;
2114 sal_Int32 aRectMinY2 = nMinY + aRadius;
2115
2116 // Draw corner rectangles
2117 tools::Rectangle aLowerRight( aRectMaxX1, aRectMaxY1, aRectMaxX2, aRectMaxY2 );
2118 tools::Rectangle aUpperLeft ( aRectMinX1, aRectMinY1, aRectMinX2, aRectMinY2 );
2119 tools::Rectangle aLowerLeft ( aRectMinX1, aRectMaxY1, aRectMinX2, aRectMaxY2 );
2120 tools::Rectangle aUpperRight( aRectMaxX1, aRectMinY1, aRectMaxX2, aRectMinY2 );
2121
2122 mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerRight ) ), lclCornerRectTransparency );
2123 mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperLeft ) ), lclCornerRectTransparency );
2124 mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerLeft ) ), lclCornerRectTransparency );
2125 mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperRight ) ), lclCornerRectTransparency );
2126}
2127
2128void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
2129 SCCOL nRefEndX, SCROW nRefEndY,
2130 const Color& rColor, sal_uInt16 nType )
2131{
2132 PutInOrder( nRefStartX, nRefEndX );
2133 PutInOrder( nRefStartY, nRefEndY );
2134
2135 if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
2136 mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
2137
2138 if ( !(nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
2139 nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1) ) // +1 because it touches next cells left/top
2140 return;
2141
2142 tools::Long nMinX = nScrX;
2143 tools::Long nMinY = nScrY;
2144 tools::Long nMaxX = nScrX+nScrW-1;
2145 tools::Long nMaxY = nScrY+nScrH-1;
2146 if ( bLayoutRTL )
2147 std::swap( nMinX, nMaxX );
2148 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2149
2150 bool bTop = false;
2151 bool bBottom = false;
2152 bool bLeft = false;
2153 bool bRight = false;
2154
2155 tools::Long nPosY = nScrY;
2156 bool bNoStartY = ( nY1 < nRefStartY );
2157 bool bNoEndY = false;
2158 for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
2159 {
2160 SCROW nY = pRowInfo[nArrY].nRowNo;
2161
2162 if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2163 {
2164 nMinY = nPosY - 1;
2165 bTop = true;
2166 }
2167 if ( nY==nRefEndY )
2168 {
2169 nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
2170 bBottom = true;
2171 }
2172 if ( nY>nRefEndY && bNoEndY )
2173 {
2174 nMaxY = nPosY - 1;
2175 bBottom = true;
2176 }
2177 bNoStartY = ( nY < nRefStartY );
2178 bNoEndY = ( nY < nRefEndY );
2179 nPosY += pRowInfo[nArrY].nHeight;
2180 }
2181
2182 tools::Long nPosX = nScrX;
2183 if ( bLayoutRTL )
2184 nPosX += nMirrorW - 1; // always in pixels
2185
2186 for (SCCOL nX=nX1; nX<=nX2+1; nX++)
2187 {
2188 if ( nX==nRefStartX )
2189 {
2190 nMinX = nPosX - nLayoutSign;
2191 bLeft = true;
2192 }
2193 if ( nX==nRefEndX )
2194 {
2195 nMaxX = nPosX + ( pRowInfo[0].basicCellInfo(nX).nWidth - 1 ) * nLayoutSign;
2196 bRight = true;
2197 }
2198 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2199 }
2200
2201 if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
2202 return;
2203
2204 if ( nType == SC_CAT_DELETE_ROWS )
2205 bLeft = bRight = bBottom = false;
2206 else if ( nType == SC_CAT_DELETE_COLS )
2207 bTop = bBottom = bRight = false;
2208
2209 mpDev->SetLineColor( rColor );
2210 if (bTop && bBottom && bLeft && bRight)
2211 {
2212 mpDev->SetFillColor();
2213 mpDev->DrawRect( tools::Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2214 }
2215 else
2216 {
2217 if (bTop)
2218 {
2219 mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
2220 if ( nType == SC_CAT_DELETE_ROWS )
2221 mpDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
2222 }
2223 if (bBottom)
2224 mpDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
2225 if (bLeft)
2226 {
2227 mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
2228 if ( nType == SC_CAT_DELETE_COLS )
2229 mpDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
2230 }
2231 if (bRight)
2232 mpDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
2233 }
2234 if ( bLeft && bTop )
2235 {
2236 mpDev->SetLineColor();
2237 mpDev->SetFillColor( rColor );
2238 mpDev->DrawRect( tools::Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
2239 }
2240}
2241
2243{
2244 ScChangeTrack* pTrack = mpDoc->GetChangeTrack();
2246 if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
2247 return; // nothing there or hidden
2248
2249 ScActionColorChanger aColorChanger(*pTrack);
2250
2251 // clipping happens from the outside
2253
2254 SCCOL nEndX = nX2;
2255 SCROW nEndY = nY2;
2256 if ( nEndX < mpDoc->MaxCol() ) ++nEndX; // also from the next cell since the mark
2257 if ( nEndY < mpDoc->MaxRow() ) ++nEndY; // protrudes from the preceding cell
2258 ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
2259 const ScChangeAction* pAction = pTrack->GetFirst();
2260 while (pAction)
2261 {
2262 if ( pAction->IsVisible() )
2263 {
2264 ScChangeActionType eActionType = pAction->GetType();
2265 const ScBigRange& rBig = pAction->GetBigRange();
2266 if ( rBig.aStart.Tab() == nTab )
2267 {
2268 ScRange aRange = rBig.MakeRange( *mpDoc );
2269
2270 if ( eActionType == SC_CAT_DELETE_ROWS )
2271 aRange.aEnd.SetRow( aRange.aStart.Row() );
2272 else if ( eActionType == SC_CAT_DELETE_COLS )
2273 aRange.aEnd.SetCol( aRange.aStart.Col() );
2274
2275 if ( aRange.Intersects( aViewRange ) &&
2276 ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2277 {
2278 aColorChanger.Update( *pAction );
2279 Color aColor( aColorChanger.GetColor() );
2280 DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2281 aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2282
2283 }
2284 }
2285 if ( eActionType == SC_CAT_MOVE &&
2286 static_cast<const ScChangeActionMove*>(pAction)->
2287 GetFromRange().aStart.Tab() == nTab )
2288 {
2289 ScRange aRange = static_cast<const ScChangeActionMove*>(pAction)->
2290 GetFromRange().MakeRange( *mpDoc );
2291 if ( aRange.Intersects( aViewRange ) &&
2292 ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2293 {
2294 aColorChanger.Update( *pAction );
2295 Color aColor( aColorChanger.GetColor() );
2296 DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2297 aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2298 }
2299 }
2300 }
2301
2302 pAction = pAction->GetNext();
2303 }
2304}
2305
2307{
2308 Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
2309 tools::Long nOneXLogic = aOnePixel.Width();
2310 tools::Long nOneYLogic = aOnePixel.Height();
2311
2312 // See more about bWorksInPixels in ScOutputData::DrawGrid
2313 bool bWorksInPixels = false;
2314 if (eType == OUTTYPE_WINDOW)
2315 bWorksInPixels = true;
2316
2317 tools::Long nOneX = 1;
2318 tools::Long nOneY = 1;
2319 if (!bWorksInPixels)
2320 {
2321 nOneX = nOneXLogic;
2322 nOneY = nOneYLogic;
2323 }
2324
2325 tools::Long nInitPosX = nScrX;
2326 if ( bLayoutRTL )
2327 nInitPosX += nMirrorW - 1; // always in pixels
2328 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2329
2330 tools::Long nPosY = nScrY;
2331 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2332 {
2333 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2334 if ( pThisRowInfo->bChanged )
2335 {
2336 tools::Long nPosX = nInitPosX;
2337 for (SCCOL nX=nX1; nX<=nX2; nX++)
2338 {
2339 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
2340 bool bIsMerged = false;
2341
2342 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2343 {
2344 // find start of merged cell
2345 bIsMerged = true;
2346 SCROW nY = pRowInfo[nArrY].nRowNo;
2347 SCCOL nMergeX = nX;
2348 SCROW nMergeY = nY;
2349 mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2350 }
2351
2352 std::shared_ptr<sc::Sparkline> pSparkline;
2353 ScAddress aCurrentAddress(nX, pRowInfo[nArrY].nRowNo, nTab);
2354
2355 if (!mpDoc->ColHidden(nX, nTab) && (pSparkline = mpDoc->GetSparkline(aCurrentAddress))
2356 && (bIsMerged || (!pInfo->bHOverlapped && !pInfo->bVOverlapped)))
2357 {
2358 const tools::Long nWidth = pRowInfo[0].basicCellInfo(nX).nWidth;
2359 const tools::Long nHeight = pThisRowInfo->nHeight;
2360
2361 Point aPoint(nPosX, nPosY);
2362 Size aSize(nWidth, nHeight);
2363
2364 sc::SparklineRenderer renderer(*mpDoc);
2365 renderer.render(pSparkline, rRenderContext, tools::Rectangle(aPoint, aSize), nOneX, nOneY, double(aZoomX), double(aZoomY));
2366 }
2367
2368 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2369 }
2370 }
2371 nPosY += pThisRowInfo->nHeight;
2372 }
2373
2374}
2375
2376//TODO: moggi Need to check if this can't be written simpler
2378{
2379
2380 tools::Long nInitPosX = nScrX;
2381 if ( bLayoutRTL )
2382 nInitPosX += nMirrorW - 1; // always in pixels
2383 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2384
2385 tools::Long nPosY = nScrY;
2386 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2387 {
2388 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2389 if ( pThisRowInfo->bChanged )
2390 {
2391 tools::Long nPosX = nInitPosX;
2392 for (SCCOL nX=nX1; nX<=nX2; nX++)
2393 {
2394 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
2395 bool bIsMerged = false;
2396
2397 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2398 {
2399 // find start of merged cell
2400 bIsMerged = true;
2401 SCROW nY = pRowInfo[nArrY].nRowNo;
2402 SCCOL nMergeX = nX;
2403 SCROW nMergeY = nY;
2404 mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2405 }
2406
2407 if (!mpDoc->ColHidden(nX, nTab) && mpDoc->GetNote(nX, pRowInfo[nArrY].nRowNo, nTab)
2408 && (bIsMerged || (!pInfo->bHOverlapped && !pInfo->bVOverlapped)))
2409 {
2410
2411 const bool bIsDarkBackground = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor.IsDark();
2412 const Color aColor = pInfo->pBackground->GetColor();
2413 if ( aColor == COL_AUTO ? bIsDarkBackground : aColor.IsDark() )
2414 rRenderContext.SetLineColor(COL_WHITE);
2415 else
2416 rRenderContext.SetLineColor(COL_BLACK);
2417
2418 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2419 if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2420 rRenderContext.SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2421 else
2422 rRenderContext.SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCCOMMENTS).nColor );
2423
2424 tools::Long nMarkX = nPosX + ( pRowInfo[0].basicCellInfo(nX).nWidth - 2 ) * nLayoutSign;
2425 if ( bIsMerged || pInfo->bMerged )
2426 {
2427 // if merged, add widths of all cells
2428 SCCOL nNextX = nX + 1;
2429 while ( nNextX <= nX2 + 1 && pThisRowInfo->cellInfo(nNextX).bHOverlapped )
2430 {
2431 nMarkX += pRowInfo[0].basicCellInfo(nNextX).nWidth * nLayoutSign;
2432 ++nNextX;
2433 }
2434 }
2435 // DPI/ZOOM 100/100 => 10, 100/50 => 7, 100/150 => 13
2436 // DPI/ZOOM 150/100 => 13, 150/50 => 8.5, 150/150 => 17.5
2437 const double nSize( rRenderContext.GetDPIScaleFactor() * aZoomX * 6 + 4);
2438 Point aPoints[3];
2439 aPoints[0] = Point(nMarkX, nPosY);
2440 aPoints[0].setX( bLayoutRTL ? aPoints[0].X() + nSize : aPoints[0].X() - nSize );
2441 aPoints[1] = Point(nMarkX, nPosY);
2442 aPoints[2] = Point(nMarkX, nPosY + nSize);
2443 tools::Polygon aPoly(3, aPoints);
2444
2445 if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2446 rRenderContext.DrawPolygon(aPoly);
2447 }
2448
2449 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2450 }
2451 }
2452 nPosY += pThisRowInfo->nHeight;
2453 }
2454}
2455
2457{
2458 bool bFirst = true;
2459
2460 tools::Long nInitPosX = nScrX;
2461 if ( bLayoutRTL )
2462 nInitPosX += nMirrorW - 1; // always in pixels
2463 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2464
2465 tools::Long nPosY = nScrY;
2466 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2467 {
2468 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2469 if ( pThisRowInfo->bChanged )
2470 {
2471 tools::Long nPosX = nInitPosX;
2472 for (SCCOL nX=nX1; nX<=nX2; nX++)
2473 {
2474 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
2475 if (!mpDoc->ColHidden(nX, nTab) && !mpDoc->GetFormula(nX, pRowInfo[nArrY].nRowNo, nTab).isEmpty()
2476 && (!pInfo->bHOverlapped && !pInfo->bVOverlapped))
2477 {
2478 if (bFirst)
2479 {
2480 rRenderContext.SetLineColor(COL_WHITE);
2481
2482 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2483 if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2484 rRenderContext.SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2485 else
2486 rRenderContext.SetFillColor(COL_LIGHTBLUE);
2487
2488 bFirst = false;
2489 }
2490
2491 tools::Long nMarkX = nPosX;
2492 tools::Long nMarkY = nPosY + pThisRowInfo->nHeight - 2;
2493 if ( pInfo->bMerged )
2494 {
2495 for (SCSIZE nNextY=nArrY+1; nNextY+1<nArrCount; nNextY++)
2496 {
2497 bool bVOver;
2498 if (pRowInfo[nNextY + 1].nRowNo == (pRowInfo[nNextY].nRowNo + 1)) {
2499 bVOver = pRowInfo[nNextY].cellInfo(nX).bVOverlapped;
2500 } else {
2501 bVOver = mpDoc->GetAttr(nX,nNextY,nTab,ATTR_MERGE_FLAG)->IsVerOverlapped();
2502 }
2503 if (!bVOver) break;
2504 nMarkY += pRowInfo[nNextY].nHeight;
2505 }
2506 }
2507 // DPI/ZOOM 100/100 => 10, 100/50 => 7, 100/150 => 13
2508 // DPI/ZOOM 150/100 => 13, 150/50 => 8.5, 150/150 => 17.5
2509 const double nSize( rRenderContext.GetDPIScaleFactor() * aZoomX * 6 + 4);
2510 Point aPoints[3];
2511 aPoints[0] = Point(nMarkX, nMarkY);
2512 aPoints[0].setX( bLayoutRTL ? aPoints[0].X() - nSize : aPoints[0].X() + nSize );
2513 aPoints[1] = Point(nMarkX, nMarkY);
2514 aPoints[2] = Point(nMarkX, nMarkY - nSize);
2515 tools::Polygon aPoly(3, aPoints);
2516
2517 if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2518 rRenderContext.DrawPolygon(aPoly);
2519 }
2520
2521 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2522 }
2523 }
2524 nPosY += pThisRowInfo->nHeight;
2525 }
2526}
2527
2529{
2530 vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >( mpDev->GetExtOutDevData() );
2531 if ( !pPDFData || !pPDFData->GetIsExportNotes() )
2532 return;
2533
2534 tools::Long nInitPosX = nScrX;
2535 if ( bLayoutRTL )
2536 {
2537 Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
2538 tools::Long nOneX = aOnePixel.Width();
2539 nInitPosX += nMirrorW - nOneX;
2540 }
2541 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2542
2543 tools::Long nPosY = nScrY;
2544 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2545 {
2546 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2547 if ( pThisRowInfo->bChanged )
2548 {
2549 tools::Long nPosX = nInitPosX;
2550 for (SCCOL nX=nX1; nX<=nX2; nX++)
2551 {
2552 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
2553 bool bIsMerged = false;
2554 SCROW nY = pRowInfo[nArrY].nRowNo;
2555 SCCOL nMergeX = nX;
2556 SCROW nMergeY = nY;
2557
2558 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2559 {
2560 // find start of merged cell
2561 bIsMerged = true;
2562 mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2563 // use origin's pCell for NotePtr test below
2564 }
2565
2566 if ( mpDoc->GetNote(nMergeX, nMergeY, nTab) && ( bIsMerged ||
2567 ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2568 {
2569 tools::Long nNoteWidth = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2570 tools::Long nNoteHeight = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTY );
2571
2572 tools::Long nMarkX = nPosX + ( pRowInfo[0].basicCellInfo(nX).nWidth - nNoteWidth ) * nLayoutSign;
2573 if ( bIsMerged || pInfo->bMerged )
2574 {
2575 // if merged, add widths of all cells
2576 SCCOL nNextX = nX + 1;
2577 while ( nNextX <= nX2 + 1 && pThisRowInfo->cellInfo(nNextX).bHOverlapped )
2578 {
2579 nMarkX += pRowInfo[0].basicCellInfo(nNextX).nWidth * nLayoutSign;
2580 ++nNextX;
2581 }
2582 }
2583 if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2584 {
2585 tools::Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
2586 const ScPostIt* pNote = mpDoc->GetNote(nMergeX, nMergeY, nTab);
2587
2588 // Note title is the cell address (as on printed note pages)
2589 ScAddress aAddress( nMergeX, nMergeY, nTab );
2590 OUString aTitle(aAddress.Format(ScRefFlags::VALID, mpDoc, mpDoc->GetAddressConvention()));
2591
2592 // Content has to be a simple string without line breaks
2593 OUString aContent = pNote->GetText();
2594 aContent = aContent.replaceAll("\n", " ");
2595
2596 vcl::PDFNote aNote;
2597 aNote.Title = aTitle;
2598 aNote.Contents = aContent;
2599 pPDFData->CreateNote( aNoteRect, aNote );
2600 }
2601 }
2602
2603 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2604 }
2605 }
2606 nPosY += pThisRowInfo->nHeight;
2607 }
2608}
2609
2611{
2612 if (!bAnyClipped)
2613 return;
2614
2615 Color aArrowFillCol( SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCTEXTOVERFLOW).nColor );
2616 const bool bIsDarkBackground = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor.IsDark();
2617
2618 DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
2619
2620 tools::Long nInitPosX = nScrX;
2621 if ( bLayoutRTL )
2622 nInitPosX += nMirrorW - 1; // always in pixels
2623 tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2624
2625 tools::Rectangle aCellRect;
2626 tools::Long nPosY = nScrY;
2627 for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2628 {
2629 RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2630 if ( pThisRowInfo->bChanged )
2631 {
2632 SCROW nY = pThisRowInfo->nRowNo;
2633 tools::Long nPosX = nInitPosX;
2634 for (SCCOL nX=nX1; nX<=nX2; nX++)
2635 {
2636 ScCellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
2637 if (pInfo->nClipMark != ScClipMark::NONE)
2638 {
2639 if (pInfo->bHOverlapped || pInfo->bVOverlapped)
2640 {
2641 // merge origin may be outside of visible area - use document functions
2642
2643 SCCOL nOverX = nX;
2644 SCROW nOverY = nY;
2645 tools::Long nStartPosX = nPosX;
2646 tools::Long nStartPosY = nPosY;
2647
2648 while ( nOverX > 0 && ( mpDoc->GetAttr(
2649 nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Hor ) )
2650 {
2651 --nOverX;
2652 nStartPosX -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2653 }
2654
2655 while ( nOverY > 0 && ( mpDoc->GetAttr(
2656 nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Ver ) )
2657 {
2658 --nOverY;
2659 nStartPosY -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2660 }
2661
2662 tools::Long nOutWidth = static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2663 tools::Long nOutHeight = static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2664
2665 const ScMergeAttr* pMerge = mpDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
2666 SCCOL nCountX = pMerge->GetColMerge();
2667 for (SCCOL i=1; i<nCountX; i++)
2668 nOutWidth += mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX;
2669 SCROW nCountY = pMerge->GetRowMerge();
2670 nOutHeight += mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY);
2671
2672 if ( bLayoutRTL )
2673 nStartPosX -= nOutWidth - 1;
2674 aCellRect = tools::Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
2675 }
2676 else
2677 {
2678 tools::Long nOutWidth = pRowInfo[0].basicCellInfo(nX).nWidth;
2679 tools::Long nOutHeight = pThisRowInfo->nHeight;
2680
2681 if ( pInfo->bMerged && pInfo->pPatternAttr )
2682 {
2683 SCCOL nOverX = nX;
2684 SCROW nOverY = nY;
2685 const ScMergeAttr* pMerge =
2687 SCCOL nCountX = pMerge->GetColMerge();
2688 for (SCCOL i=1; i<nCountX; i++)
2689 nOutWidth += mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX;
2690 SCROW nCountY = pMerge->GetRowMerge();
2691 nOutHeight += mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY);
2692 }
2693
2694 tools::Long nStartPosX = nPosX;
2695 if ( bLayoutRTL )
2696 nStartPosX -= nOutWidth - 1;
2697 // #i80447# create aCellRect from two points in case nOutWidth is 0
2698 aCellRect = tools::Rectangle( Point( nStartPosX, nPosY ),
2699 Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
2700 }
2701
2702 aCellRect.AdjustBottom( -1 ); // don't paint over the cell grid
2703 if ( bLayoutRTL )
2704 aCellRect.AdjustLeft(1 );
2705 else
2706 aCellRect.AdjustRight( -1 );
2707
2708 tools::Long nMarkPixel = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2709 Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
2710
2711 const Color aColor = pInfo->pBackground ? pInfo->pBackground->GetColor() : COL_AUTO;
2712 if ( aColor == COL_AUTO ? bIsDarkBackground : aColor.IsDark() )
2713 mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::WhiteLine );
2714 else
2715 mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::BlackLine );
2716
2717 if (bVertical)
2718 {
2720 {
2721 // visually top
2722 tools::Rectangle aMarkRect = aCellRect;
2723 aMarkRect.SetBottom(aCellRect.Top() + nMarkPixel - 1);
2724 SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true, true);
2725 }
2727 {
2728 // visually bottom
2729 tools::Rectangle aMarkRect = aCellRect;
2730 aMarkRect.SetTop(aCellRect.Bottom() + nMarkPixel + 1);
2731 SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
2732 true);
2733 }
2734 }
2735 else
2736 {
2738 {
2739 // visually left
2740 tools::Rectangle aMarkRect = aCellRect;
2741 aMarkRect.SetRight(aCellRect.Left() + nMarkPixel - 1);
2742 SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true,
2743 false);
2744 }
2746 {
2747 // visually right
2748 tools::Rectangle aMarkRect = aCellRect;
2749 aMarkRect.SetLeft(aCellRect.Right() - nMarkPixel + 1);
2750 SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
2751 false);
2752 }
2753 }
2754 }
2755 nPosX += pRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign;
2756 }
2757 }
2758 nPosY += pThisRowInfo->nHeight;
2759 }
2760
2761 mpDev->SetDrawMode(nOldDrawMode);
2762}
2763
2764/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawModeFlags
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:150
ScChangeActionType
Definition: chgtrack.hxx:63
@ SC_CAT_MOVE
Definition: chgtrack.hxx:71
@ SC_CAT_DELETE_TABS
Definition: chgtrack.hxx:70
@ SC_CAT_INSERT_TABS
Definition: chgtrack.hxx:67
@ SC_CAT_DELETE_ROWS
Definition: chgtrack.hxx:69
@ SC_CAT_DELETE_COLS
Definition: chgtrack.hxx:68
@ SC_CAT_INSERT_ROWS
Definition: chgtrack.hxx:66
@ SC_CAT_INSERT_COLS
Definition: chgtrack.hxx:65
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
const Size & GetSizePixel() const
sal_uInt32 GetValue() const
bool IsFullyTransparent() const
bool IsDark() const
sal_uInt8 GetAlpha() const
bool IsTransparent() const
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
float GetDPIScaleFactor() 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 SetLineColor()
void DrawPolygon(const tools::Polygon &rPoly)
void SetClipRegion()
void SetFillColor()
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
void SetDrawMode(DrawModeFlags nDrawMode)
DrawModeFlags GetDrawMode() const
void IntersectClipRegion(const tools::Rectangle &rRect)
void setX(tools::Long nX)
constexpr tools::Long X() const
Color GetColor() const
Definition: chgtrack.hxx:59
const ScAppOptions & rOpt
Definition: chgtrack.hxx:50
void Update(const ScChangeAction &rAction)
Definition: output.cxx:94
ScActionColorChanger(const ScChangeTrack &rTrack)
Definition: output.cxx:86
OUString aLastUserName
Definition: chgtrack.hxx:52
const std::set< OUString > & rUsers
Definition: chgtrack.hxx:51
sal_uInt16 nLastUserIndex
Definition: chgtrack.hxx:53
SCTAB Tab() const
Definition: address.hxx:283
void SetCol(SCCOL nColP)
Definition: address.hxx:291
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
SCROW Row() const
Definition: address.hxx:274
void SetRow(SCROW nRowP)
Definition: address.hxx:287
SCCOL Col() const
Definition: address.hxx:279
Color GetTrackMoveColor() const
Definition: appoptio.hxx:65
Color GetTrackInsertColor() const
Definition: appoptio.hxx:61
Color GetTrackContentColor() const
Definition: appoptio.hxx:59
Color GetTrackDeleteColor() const
Definition: appoptio.hxx:63
sal_Int64 Tab() const
Definition: bigrange.hxx:46
ScBigAddress aStart
Definition: bigrange.hxx:108
ScRange MakeRange(const ScDocument &rDoc) const
Definition: bigrange.hxx:134
ScBigRange & GetBigRange()
Definition: chgtrack.hxx:229
bool IsVisible() const
Definition: chgtrack.cxx:143
ScChangeActionType GetType() const
Definition: chgtrack.hxx:315
ScChangeAction * GetNext() const
Definition: chgtrack.hxx:320
const OUString & GetUser() const
Definition: chgtrack.hxx:347
ScChangeAction * GetFirst() const
Definition: chgtrack.hxx:951
bool ShowChanges() const
Definition: chgviset.hxx:77
bool DeleteCirclesAt(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1148
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
SC_DLLPUBLIC std::shared_ptr< sc::Sparkline > GetSparkline(ScAddress const &rPosition)
Returns sparkline at the address if it exists.
Definition: document.cxx:6495
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4122
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5556
tools::Long GetScaledRowHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale) const
Definition: document.cxx:4198
SC_DLLPUBLIC bool IsTabProtected(SCTAB nTab) const
Definition: documen3.cxx:1905
SC_DLLPUBLIC void InitDrawLayer(SfxObjectShell *pDocShell=nullptr)
Definition: documen9.cxx:105
bool IsIdleEnabled() const
Definition: document.hxx:2207
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:892
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uInt32 nIndex) const
Definition: documen4.cxx:873
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:893
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
Definition: document.cxx:6587
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4355
SC_DLLPUBLIC bool EnsureFormulaCellResults(const ScRange &rRange, bool bSkipRunning=false)
Make sure all of the formula cells in the specified range have been fully calculated.
ScChangeViewSettings * GetChangeViewSettings() const
Definition: document.hxx:2243
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4369
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1084
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4416
void EnableIdle(bool bDo)
Definition: document.hxx:2208
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5466
SC_DLLPUBLIC OUString GetFormula(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3706
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4430
sc::IconSetBitmapMap & GetIconSetBitmapMap()
Definition: documen2.cxx:1499
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2494
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:974
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4684
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
Definition: documen4.cxx:791
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4719
void StripHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2, SCTAB nTab)
Definition: document.cxx:4670
bool IsRunning() const
bool GetDirty() const
bool IsChanged() const
ScAddress aPos
static SvxBrushItem * GetEmptyBrushItem()
Definition: global.hxx:606
void AddHorLine(bool bWorksInPixels, tools::Long nX1, tools::Long nX2, tools::Long nY, bool bDashed=false)
Definition: gridmerg.cxx:96
void Flush()
Definition: gridmerg.cxx:184
void AddVerLine(bool bWorksInPixels, tools::Long nX, tools::Long nY1, tools::Long nY2, bool bDashed=false)
Definition: gridmerg.cxx:140
static BitmapEx & getBitmap(sc::IconSetBitmapMap &rBitmapMap, ScIconSetType eType, sal_Int32 nIndex)
SCCOL GetColMerge() const
Definition: attrib.hxx:71
SCROW GetRowMerge() const
Definition: attrib.hxx:72
void DrawChangeTrack()
Definition: output.cxx:2242
ScOutputData(OutputDevice *pNewDev, ScOutputType eNewType, ScTableInfo &rTabInfo, ScDocument *pNewDoc, SCTAB nNewTab, tools::Long nNewScrX, tools::Long nNewScrY, SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2, double nPixelPerTwipsX, double nPixelPerTwipsY, const Fraction *pZoomX=nullptr, const Fraction *pZoomY=nullptr)
Definition: output.cxx:140
ScTableInfo & mrTabInfo
Definition: output.hxx:181
SCROW nY2
Definition: output.hxx:194
bool bPagebreakMode
Definition: output.hxx:215
void DrawOneChange(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor, sal_uInt16 nType)
Definition: output.cxx:2128
ReferenceMark FillReferenceMark(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor)
Definition: output.cxx:1917
void DrawClear()
Definition: output.cxx:1332
tools::Long nScrY
Definition: output.hxx:187
SCTAB nTab
Definition: output.hxx:185
SCCOL nEditCol
Definition: output.hxx:210
VclPtr< OutputDevice > mpDev
Definition: output.hxx:178
Fraction aZoomY
Definition: output.hxx:203
VclPtr< OutputDevice > mpRefDevice
Definition: output.hxx:179
tools::Long nScrW
Definition: output.hxx:188
bool bVertical
Definition: output.hxx:236
tools::Long nScrH
Definition: output.hxx:189
void SetEditCell(SCCOL nCol, SCROW nRow)
Definition: output.cxx:272
void DrawClipMarks()
Definition: output.cxx:2610
bool bMetaFile
Definition: output.hxx:213
void AddPDFNotes()
Definition: output.cxx:2528
double mnPPTY
Definition: output.hxx:201
bool bEditMode
Definition: output.hxx:209
SCCOL nVisX2
Definition: output.hxx:197
bool mbSyntaxMode
Definition: output.hxx:221
void DrawRotatedFrame(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1511
void SetSnapPixel()
Definition: output.cxx:267
bool bMarkClipped
Definition: output.hxx:231
SCCOL nVisX1
Definition: output.hxx:195
tools::Long nMirrorW
Definition: output.hxx:190
void SetCellRotations()
Definition: output.cxx:619
SCCOL nX1
Definition: output.hxx:191
bool bAnyClipped
Definition: output.hxx:235
SCROW nEditRow
Definition: output.hxx:211
double mnPPTX
Definition: output.hxx:200
void SetSyntaxMode(bool bNewMode)
Definition: output.cxx:284
SCROW nVisY2
Definition: output.hxx:198
bool bSnapPixel
Definition: output.hxx:233
void SetMirrorWidth(tools::Long nNew)
Definition: output.cxx:237
SCCOL nX2
Definition: output.hxx:193
ScOutputType eType
Definition: output.hxx:199
bool bShowSpellErrors
Definition: output.hxx:230
RowInfo * pRowInfo
Definition: output.hxx:182
VclPtr< OutputDevice > pFmtDevice
Definition: output.hxx:180
Fraction aZoomX
Definition: output.hxx:202
void DrawSparklines(vcl::RenderContext &rRenderContext)
Definition: output.cxx:2306
void SetShowNullValues(bool bSet)
Definition: output.cxx:252
void FindChanged()
Definition: output.cxx:1813
SCROW nVisY1
Definition: output.hxx:196
bool SetChangedClip()
Definition: output.cxx:1772
void DrawFrame(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1387
void DrawExtraShadow(bool bLeft, bool bTop, bool bRight, bool bBottom)
Definition: output.cxx:1191
ScDocument * mpDoc
Definition: output.hxx:184
void SetShowSpellErrors(bool bSet)
Definition: output.cxx:262
SCROW nY1
Definition: output.hxx:192
void DrawShadow()
Definition: output.cxx:1186
void DrawNoteMarks(vcl::RenderContext &rRenderContext)
Definition: output.cxx:2377
bool bLayoutRTL
Definition: output.hxx:238
bool mbUseStyleColor
Definition: output.hxx:218
void DrawBackground(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1022
bool bSolidBackground
Definition: output.hxx:216
void SetGridColor(const Color &rColor)
Definition: output.cxx:242
void SetMarkClipped(bool bSet)
Definition: output.cxx:247
SCSIZE nArrCount
Definition: output.hxx:183
tools::Long nScrX
Definition: output.hxx:186
void DrawGrid(vcl::RenderContext &rRenderContext, bool bGrid, bool bPage, bool bMergeCover=false)
Definition: output.cxx:296
void DrawDocumentBackground()
Definition: output.cxx:816
std::optional< Color > mxValueColor
Definition: output.hxx:222
bool mbShowNullValues
Definition: output.hxx:228
Color aGridColor
Definition: output.hxx:226
void SetMetaFileMode(bool bNewMode)
Definition: output.cxx:279
vcl::Region GetChangedAreaRegion()
Definition: output.cxx:1730
bool mbShowFormulas
Definition: output.hxx:229
std::optional< Color > mxFormulaColor
Definition: output.hxx:224
const sc::SpellCheckContext * mpSpellCheckCxt
Definition: output.hxx:242
void SetSpellCheckContext(const sc::SpellCheckContext *pCxt)
Definition: output.cxx:221
bool bTabProtected
Definition: output.hxx:237
std::unique_ptr< drawinglayer::processor2d::BaseProcessor2D > CreateProcessor2D()
Definition: output.cxx:1710
void SetShowFormulas(bool bSet)
Definition: output.cxx:257
std::optional< Color > mxTextColor
Definition: output.hxx:223
void DrawRefMark(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor, bool bHandle)
Draws reference mark and returns its properties.
Definition: output.cxx:2005
void SetPagebreakMode(ScPageBreakData *pPageData)
Definition: output.cxx:587
void SetContentDevice(OutputDevice *pContentDev)
Definition: output.cxx:226
void DrawFormulaMarks(vcl::RenderContext &rRenderContext)
Definition: output.cxx:2456
size_t GetCount() const
Definition: pagedata.hxx:73
ScPrintRangeData & GetData(size_t i)
Definition: pagedata.cxx:60
Degree100 GetRotateVal(const SfxItemSet *pCondSet) const
Definition: patattr.cxx:1454
ScRotateDir GetRotateDir(const SfxItemSet *pCondSet) const
Definition: patattr.cxx:1468
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:73
Additional class containing cell annotation data.
Definition: postit.hxx:58
OUString GetText() const
Returns the caption text of this note.
Definition: postit.cxx:527
const ScRange & GetPrintRange() const
Definition: pagedata.hxx:44
static void DeleteInterpretProgress()
Definition: progress.cxx:152
static void CreateInterpretProgress(ScDocument *pDoc, bool bWait=true)
Definition: progress.cxx:132
bool GetHideCell() const
Definition: attrib.hxx:152
bool GetProtection() const
Definition: attrib.hxx:148
ScAddress aEnd
Definition: address.hxx:498
bool Intersects(const ScRange &rRange) const
Definition: address.hxx:734
ScAddress aStart
Definition: address.hxx:497
static bool IsActionShown(const ScChangeAction &rAction, const ScChangeViewSettings &rSettings, ScDocument &rDocument)
Definition: viewutil.cxx:135
const SdrPage * GetPage(sal_uInt16 nPgNum) const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
bool GetHighContrastMode() const
const Color & GetWindowTextColor() const
const Color & GetColor() const
static tools::Polygon DrawArrow(OutputDevice &rOut, const tools::Rectangle &rRect, const Size &rSize, const Color &rCol, bool bLeftOrTop, bool bVertical)
sal_uInt16 GetWidth() const
const Color & GetColor() const
SvxShadowLocation GetLocation() const
void setViewport(const basegfx::B2DRange &rNew)
void setViewTransformation(const basegfx::B2DHomMatrix &rNew)
void setVisualizedPage(const css::uno::Reference< css::drawing::XDrawPage > &rNew)
Render a provided sparkline into the input rectangle.
void render(std::shared_ptr< sc::Sparkline > const &pSparkline, vcl::RenderContext &rRenderContext, tools::Rectangle const &rRectangle, tools::Long nOneX, tools::Long nOneY, double fScaleX, double fScaleY)
Class shared between grid windows to cache spelling results.
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveRange(sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow, const Color *pForceColor) const
void SetRowHeight(sal_Int32 nRow, sal_Int32 nHeight)
bool HasCellRotation() const
void SetColWidth(sal_Int32 nCol, sal_Int32 nWidth)
void SetXOffset(sal_Int32 nXOffset)
void SetYOffset(sal_Int32 nYOffset)
sal_Int32 GetColCount() const
void SetClipRange(sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow)
void SetCellRotation(sal_Int32 nCol, sal_Int32 nRow, SvxRotateMode eRotMode, double fOrientation)
sal_Int32 GetRowCount() const
sal_uInt16 Count() const
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr void SetRight(tools::Long v)
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr void SetBottom(tools::Long v)
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
void CreateNote(const tools::Rectangle &rRect, const PDFNote &rNote, sal_Int32 nPageNr=-1)
bool GetIsExportNotes() const
void Union(const tools::Rectangle &rRegion)
constexpr ::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
constexpr ::Color COL_GREEN(0x00, 0x80, 0x00)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_MAGENTA(0x80, 0x00, 0x80)
constexpr ::Color COL_LIGHTMAGENTA(0xFF, 0x00, 0xFF)
constexpr ::Color COL_BROWN(0x80, 0x80, 0x00)
constexpr ::Color COL_RED(0x80, 0x00, 0x00)
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTBLUE(0x00, 0x00, 0xFF)
constexpr ::Color COL_CYAN(0x00, 0x80, 0x80)
constexpr ::Color COL_BLUE(0x00, 0x00, 0x80)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
ScIconSetType
Definition: colorscale.hxx:189
double toRadians(D x)
ScRotateDir
Definition: fillinfo.hxx:40
const SCCOL SC_ROTMAX_NONE
Definition: fillinfo.hxx:189
ScShadowPart
Definition: fillinfo.hxx:54
@ SC_SHADOW_VSTART
Definition: fillinfo.hxx:56
@ SC_SHADOW_VERT
Definition: fillinfo.hxx:58
@ SC_SHADOW_CORNER
Definition: fillinfo.hxx:59
@ SC_SHADOW_HSTART
Definition: fillinfo.hxx:55
@ SC_SHADOW_HORIZ
Definition: fillinfo.hxx:57
const sal_uInt8 SC_CLIPMARK_SIZE
Definition: fillinfo.hxx:51
DocumentType eType
ScBreakType
Definition: global.hxx:139
@ CELLTYPE_FORMULA
Definition: global.hxx:276
sal_Int32 nIndex
sal_uInt16 nPos
#define SAL_INFO_IF(condition, area, stream)
std::unique_ptr< sal_Int32[]> pData
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
std::map< OUString, BitmapEx > IconSetBitmapMap
Definition: document.hxx:217
CALCPAGEBREAKAUTOMATIC
CALCPROTECTEDBACKGROUND
CALCPAGEBREAKMANUAL
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
static const SvxBrushItem * lcl_FindBackground(const ScDocument *pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: output.cxx:712
const Color nAuthorColor[SC_AUTHORCOLORCOUNT]
Definition: output.cxx:79
static bool lcl_EqualBack(const RowInfo &rFirst, const RowInfo &rOther, SCCOL nX1, SCCOL nX2, bool bShowProt, bool bPagebreakMode)
Definition: output.cxx:750
static tools::Long lclGetSnappedY(const OutputDevice &rDev, tools::Long nPosY, bool bSnapPixel)
Definition: output.cxx:1382
#define SC_AUTHORCOLORCOUNT
Definition: output.cxx:77
static tools::Long lclGetSnappedX(const OutputDevice &rDev, tools::Long nPosX, bool bSnapPixel)
Definition: output.cxx:1377
static ScRotateDir lcl_GetRotateDir(const ScDocument *pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: output.cxx:679
ScOutputType
Definition: output.hxx:59
@ OUTTYPE_WINDOW
Definition: output.hxx:59
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
SvxRotateMode
SVX_ROTATE_MODE_BOTTOM
SVX_ROTATE_MODE_STANDARD
SVX_ROTATE_MODE_CENTER
SVX_ROTATE_MODE_TOP
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
constexpr TypedWhichId< SvxBrushItem > ATTR_BACKGROUND(148)
constexpr TypedWhichId< SvxRotateModeItem > ATTR_ROTATE_MODE(136)
constexpr TypedWhichId< ScProtectionAttr > ATTR_PROTECTION(149)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
#define SC_MOD()
Definition: scmod.hxx:247
Describes reference mark to be drawn, position & size in TWIPs.
Definition: output.hxx:65
bool bEmptyBack
Definition: fillinfo.hxx:242
SCROW nRowNo
Definition: fillinfo.hxx:239
SCCOL nRotMaxCol
Definition: fillinfo.hxx:240
ScCellInfo & cellInfo(SCCOL nCol)
Definition: fillinfo.hxx:197
ScBasicCellInfo & basicCellInfo(SCCOL nCol)
Definition: fillinfo.hxx:210
sal_uInt16 nHeight
Definition: fillinfo.hxx:238
bool bChanged
Definition: fillinfo.hxx:245
sal_uInt16 nWidth
Definition: fillinfo.hxx:110
ScRotateDir nRotateDir
Definition: fillinfo.hxx:173
const SvxShadowItem * pVShadowOrigin
Definition: fillinfo.hxx:168
const SfxItemSet * pConditionSet
Definition: fillinfo.hxx:154
const SvxShadowItem * pHShadowOrigin
Definition: fillinfo.hxx:167
ScClipMark nClipMark
Definition: fillinfo.hxx:172
bool bHideGrid
Definition: fillinfo.hxx:183
ScShadowPart eVShadowPart
Definition: fillinfo.hxx:171
ScRefCellValue maCell
Definition: fillinfo.hxx:151
std::optional< Color > mxColorScale
Definition: fillinfo.hxx:155
bool bVOverlapped
Definition: fillinfo.hxx:177
const ScPatternAttr * pPatternAttr
Definition: fillinfo.hxx:153
ScShadowPart eHShadowPart
Definition: fillinfo.hxx:170
bool bHOverlapped
Definition: fillinfo.hxx:176
const ScDataBarInfo * pDataBar
Definition: fillinfo.hxx:156
bool bPrinted
Definition: fillinfo.hxx:182
const SvxBrushItem * pBackground
Definition: fillinfo.hxx:159
const ScIconSetInfo * pIconSet
Definition: fillinfo.hxx:157
bool bMerged
Definition: fillinfo.hxx:175
double mnZero
Definition: fillinfo.hxx:64
Color maAxisColor
Definition: fillinfo.hxx:69
Color maColor
Definition: fillinfo.hxx:65
double mnLength
Definition: fillinfo.hxx:66
bool mbGradient
Definition: fillinfo.hxx:67
tools::Long mnHeight
Definition: fillinfo.hxx:95
ScIconSetType eIconSetType
Definition: fillinfo.hxx:94
sal_Int32 nIconIndex
Definition: fillinfo.hxx:93
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
CellType getType() const
Definition: cellvalue.hxx:133
svx::frame::Array maArray
Definition: fillinfo.hxx:264
bool mbPageMode
Definition: fillinfo.hxx:269
UNDERLYING_TYPE get() const
OUString Contents
OUString Title
SvxShadowLocation
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
SVXCORE_DLLPUBLIC css::uno::Reference< css::drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage) noexcept
sal_Int32 nLength