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