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 
1727  *mpDev, aNewViewInfos );
1728 }
1729 
1730 // Printer
1731 
1733 {
1734  vcl::Region aRegion;
1735  tools::Rectangle aDrawingRect;
1736  bool bHad(false);
1737  tools::Long nPosY = nScrY;
1738  SCSIZE nArrY;
1739 
1740  aDrawingRect.SetLeft( nScrX );
1741  aDrawingRect.SetRight( nScrX+nScrW-1 );
1742 
1743  for(nArrY=1; nArrY+1<nArrCount; nArrY++)
1744  {
1745  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1746 
1747  if(pThisRowInfo->bChanged)
1748  {
1749  if(!bHad)
1750  {
1751  aDrawingRect.SetTop( nPosY );
1752  bHad = true;
1753  }
1754 
1755  aDrawingRect.SetBottom( nPosY + pRowInfo[nArrY].nHeight - 1 );
1756  }
1757  else if(bHad)
1758  {
1759  aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
1760  bHad = false;
1761  }
1762 
1763  nPosY += pRowInfo[nArrY].nHeight;
1764  }
1765 
1766  if(bHad)
1767  {
1768  aRegion.Union(mpDev->PixelToLogic(aDrawingRect));
1769  }
1770 
1771  return aRegion;
1772 }
1773 
1775 {
1776  tools::PolyPolygon aPoly;
1777 
1778  tools::Rectangle aDrawingRect;
1779  aDrawingRect.SetLeft( nScrX );
1780  aDrawingRect.SetRight( nScrX+nScrW-1 );
1781 
1782  bool bHad = false;
1783  tools::Long nPosY = nScrY;
1784  SCSIZE nArrY;
1785  for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1786  {
1787  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1788 
1789  if ( pThisRowInfo->bChanged )
1790  {
1791  if (!bHad)
1792  {
1793  aDrawingRect.SetTop( nPosY );
1794  bHad = true;
1795  }
1796  aDrawingRect.SetBottom( nPosY + pRowInfo[nArrY].nHeight - 1 );
1797  }
1798  else if (bHad)
1799  {
1800  aPoly.Insert( tools::Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
1801  bHad = false;
1802  }
1803  nPosY += pRowInfo[nArrY].nHeight;
1804  }
1805 
1806  if (bHad)
1807  aPoly.Insert( tools::Polygon( mpDev->PixelToLogic(aDrawingRect) ) );
1808 
1809  bool bRet = (aPoly.Count() != 0);
1810  if (bRet)
1811  mpDev->SetClipRegion(vcl::Region(aPoly));
1812  return bRet;
1813 }
1814 
1816 {
1817  SCCOL nX;
1818  SCSIZE nArrY;
1819 
1820  bool bWasIdleEnabled = mpDoc->IsIdleEnabled();
1821  mpDoc->EnableIdle(false);
1822  for (nArrY=0; nArrY<nArrCount; nArrY++)
1823  pRowInfo[nArrY].bChanged = false;
1824 
1825  SCCOL nCol1 = mpDoc->MaxCol(), nCol2 = 0;
1826  SCROW nRow1 = mpDoc->MaxRow(), nRow2 = 0;
1827  bool bAnyDirty = false;
1828  bool bAnyChanged = false;
1829 
1830  for (nArrY=0; nArrY<nArrCount; nArrY++)
1831  {
1832  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1833  for (nX=nX1; nX<=nX2; nX++)
1834  {
1835  const ScRefCellValue& rCell = pThisRowInfo->pCellInfo[nX+1].maCell;
1836 
1837  if (rCell.meType != CELLTYPE_FORMULA)
1838  continue;
1839 
1840  ScFormulaCell* pFCell = rCell.mpFormula;
1841  if (pFCell->IsRunning())
1842  // still being interpreted. Skip it.
1843  continue;
1844 
1845  bool bDirty = pFCell->GetDirty();
1846  bAnyChanged = bAnyChanged || pFCell->IsChanged();
1847 
1848  if (bDirty)
1849  {
1850  if (!bAnyDirty)
1851  {
1853  bAnyDirty = true;
1854  }
1855 
1856  ScAddress& rPos(pFCell->aPos);
1857  nCol1 = std::min(rPos.Col(), nCol1);
1858  nCol2 = std::max(rPos.Col(), nCol2);
1859  nRow1 = std::min(rPos.Row(), nRow1);
1860  nRow2 = std::max(rPos.Row(), nRow2);
1861 
1862  const SfxUInt32Item* pItem = mpDoc->GetAttr(rPos, ATTR_VALIDDATA);
1863  const ScValidationData* pData = mpDoc->GetValidationEntry(pItem->GetValue());
1864  if (pData)
1865  {
1866  ScRefCellValue aCell(*mpDoc, rPos);
1867  if (pData->IsDataValid(aCell, rPos))
1868  ScDetectiveFunc(*mpDoc, rPos.Tab()).DeleteCirclesAt(rPos.Col(), rPos.Row());
1869  }
1870  }
1871  }
1872  }
1873 
1874  if (bAnyDirty || bAnyChanged)
1875  {
1876  if (bAnyDirty)
1877  mpDoc->EnsureFormulaCellResults(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab), true);
1878 
1879  for (nArrY=0; nArrY<nArrCount; nArrY++)
1880  {
1881  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1882  for (nX=nX1; nX<=nX2; nX++)
1883  {
1884  const ScRefCellValue& rCell = pThisRowInfo->pCellInfo[nX+1].maCell;
1885 
1886  if (rCell.meType != CELLTYPE_FORMULA)
1887  continue;
1888 
1889  ScFormulaCell* pFCell = rCell.mpFormula;
1890  if (pFCell->IsRunning())
1891  // still being interpreted. Skip it.
1892  continue;
1893 
1894  if (!pFCell->IsChanged())
1895  // the result hasn't changed. Skip it.
1896  continue;
1897 
1898  pThisRowInfo->bChanged = true;
1899  if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
1900  {
1901  SCSIZE nOverY = nArrY + 1;
1902  while ( nOverY<nArrCount &&
1903  pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
1904  {
1905  pRowInfo[nOverY].bChanged = true;
1906  ++nOverY;
1907  }
1908  }
1909  }
1910  }
1911 
1912  if (bAnyDirty)
1914  }
1915 
1916  mpDoc->EnableIdle(bWasIdleEnabled);
1917 }
1918 
1920  SCCOL nRefEndX, SCROW nRefEndY, const Color& rColor)
1921 {
1922  ReferenceMark aResult;
1923 
1924  PutInOrder( nRefStartX, nRefEndX );
1925  PutInOrder( nRefStartY, nRefEndY );
1926 
1927  if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
1928  mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
1929 
1930  if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
1931  nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
1932  {
1933  tools::Long nMinX = nScrX;
1934  tools::Long nMinY = nScrY;
1935  tools::Long nMaxX = nScrX + nScrW - 1;
1936  tools::Long nMaxY = nScrY + nScrH - 1;
1937  if ( bLayoutRTL )
1938  {
1939  tools::Long nTemp = nMinX;
1940  nMinX = nMaxX;
1941  nMaxX = nTemp;
1942  }
1943  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1944 
1945  bool bTop = false;
1946  bool bBottom = false;
1947  bool bLeft = false;
1948  bool bRight = false;
1949 
1950  tools::Long nPosY = nScrY;
1951  bool bNoStartY = ( nY1 < nRefStartY );
1952  bool bNoEndY = false;
1953  for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
1954  {
1955  SCROW nY = pRowInfo[nArrY].nRowNo;
1956 
1957  if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
1958  {
1959  nMinY = nPosY;
1960  bTop = true;
1961  }
1962  if ( nY==nRefEndY )
1963  {
1964  nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
1965  bBottom = true;
1966  }
1967  if ( nY>nRefEndY && bNoEndY )
1968  {
1969  nMaxY = nPosY-2;
1970  bBottom = true;
1971  }
1972  bNoStartY = ( nY < nRefStartY );
1973  bNoEndY = ( nY < nRefEndY );
1974  nPosY += pRowInfo[nArrY].nHeight;
1975  }
1976 
1977  tools::Long nPosX = nScrX;
1978  if ( bLayoutRTL )
1979  nPosX += nMirrorW - 1; // always in pixels
1980 
1981  for (SCCOL nX=nX1; nX<=nX2; nX++)
1982  {
1983  if ( nX==nRefStartX )
1984  {
1985  nMinX = nPosX;
1986  bLeft = true;
1987  }
1988  if ( nX==nRefEndX )
1989  {
1990  nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
1991  bRight = true;
1992  }
1993  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
1994  }
1995 
1996  if (bTop && bBottom && bLeft && bRight)
1997  {
1998  // mnPPT[XY] already has the factor aZoom[XY] in it.
1999  aResult = ReferenceMark( nMinX / mnPPTX,
2000  nMinY / mnPPTY,
2001  ( nMaxX - nMinX ) / mnPPTX,
2002  ( nMaxY - nMinY ) / mnPPTY,
2003  nTab,
2004  rColor );
2005  }
2006  }
2007 
2008  return aResult;
2009 }
2010 
2011 void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
2012  SCCOL nRefEndX, SCROW nRefEndY,
2013  const Color& rColor, bool bHandle )
2014 {
2015  PutInOrder( nRefStartX, nRefEndX );
2016  PutInOrder( nRefStartY, nRefEndY );
2017 
2018  if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
2019  mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
2020 
2021  if ( !(nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
2022  nRefStartY <= nVisY2 && nRefEndY >= nVisY1) )
2023  return;
2024 
2025  tools::Long nMinX = nScrX;
2026  tools::Long nMinY = nScrY;
2027  tools::Long nMaxX = nScrX + nScrW - 1;
2028  tools::Long nMaxY = nScrY + nScrH - 1;
2029  if ( bLayoutRTL )
2030  {
2031  tools::Long nTemp = nMinX;
2032  nMinX = nMaxX;
2033  nMaxX = nTemp;
2034  }
2035  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2036 
2037  bool bTop = false;
2038  bool bBottom = false;
2039  bool bLeft = false;
2040  bool bRight = false;
2041 
2042  tools::Long nPosY = nScrY;
2043  bool bNoStartY = ( nY1 < nRefStartY );
2044  bool bNoEndY = false;
2045  for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
2046  {
2047  SCROW nY = pRowInfo[nArrY].nRowNo;
2048 
2049  if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2050  {
2051  nMinY = nPosY;
2052  bTop = true;
2053  }
2054  if ( nY==nRefEndY )
2055  {
2056  nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
2057  bBottom = true;
2058  }
2059  if ( nY>nRefEndY && bNoEndY )
2060  {
2061  nMaxY = nPosY-2;
2062  bBottom = true;
2063  }
2064  bNoStartY = ( nY < nRefStartY );
2065  bNoEndY = ( nY < nRefEndY );
2066  nPosY += pRowInfo[nArrY].nHeight;
2067  }
2068 
2069  tools::Long nPosX = nScrX;
2070  if ( bLayoutRTL )
2071  nPosX += nMirrorW - 1; // always in pixels
2072 
2073  for (SCCOL nX=nX1; nX<=nX2; nX++)
2074  {
2075  if ( nX==nRefStartX )
2076  {
2077  nMinX = nPosX;
2078  bLeft = true;
2079  }
2080  if ( nX==nRefEndX )
2081  {
2082  nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
2083  bRight = true;
2084  }
2085  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2086  }
2087 
2088  if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
2089  return;
2090 
2091  mpDev->SetLineColor( rColor );
2092  if (bTop && bBottom && bLeft && bRight && !comphelper::LibreOfficeKit::isActive() )
2093  {
2094  mpDev->SetFillColor();
2095  mpDev->DrawRect( tools::Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2096  }
2098  {
2099  if (bTop)
2100  mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMaxX, nMinY ) );
2101  if (bBottom)
2102  mpDev->DrawLine( Point( nMinX, nMaxY ), Point( nMaxX, nMaxY ) );
2103  if (bLeft)
2104  mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMinX, nMaxY ) );
2105  if (bRight)
2106  mpDev->DrawLine( Point( nMaxX, nMinY ), Point( nMaxX, nMaxY ) );
2107  }
2108  if ( !bHandle || !bRight || !bBottom || comphelper::LibreOfficeKit::isActive() )
2109  return;
2110 
2111  mpDev->SetLineColor( rColor );
2112  mpDev->SetFillColor( rColor );
2113 
2114  const sal_Int32 aRadius = 4;
2115 
2116  sal_Int32 aRectMaxX1 = nMaxX - nLayoutSign * aRadius;
2117  sal_Int32 aRectMaxX2 = nMaxX + nLayoutSign;
2118  sal_Int32 aRectMinX1 = nMinX - nLayoutSign;
2119  sal_Int32 aRectMinX2 = nMinX + nLayoutSign * aRadius;
2120 
2121  sal_Int32 aRectMaxY1 = nMaxY - aRadius;
2122  sal_Int32 aRectMaxY2 = nMaxY + 1;
2123  sal_Int32 aRectMinY1 = nMinY - 1;
2124  sal_Int32 aRectMinY2 = nMinY + aRadius;
2125 
2126  // Draw corner rectangles
2127  tools::Rectangle aLowerRight( aRectMaxX1, aRectMaxY1, aRectMaxX2, aRectMaxY2 );
2128  tools::Rectangle aUpperLeft ( aRectMinX1, aRectMinY1, aRectMinX2, aRectMinY2 );
2129  tools::Rectangle aLowerLeft ( aRectMinX1, aRectMaxY1, aRectMinX2, aRectMaxY2 );
2130  tools::Rectangle aUpperRight( aRectMaxX1, aRectMinY1, aRectMaxX2, aRectMinY2 );
2131 
2132  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerRight ) ), lclCornerRectTransparency );
2133  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperLeft ) ), lclCornerRectTransparency );
2134  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerLeft ) ), lclCornerRectTransparency );
2135  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperRight ) ), lclCornerRectTransparency );
2136 }
2137 
2138 void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
2139  SCCOL nRefEndX, SCROW nRefEndY,
2140  const Color& rColor, sal_uInt16 nType )
2141 {
2142  PutInOrder( nRefStartX, nRefEndX );
2143  PutInOrder( nRefStartY, nRefEndY );
2144 
2145  if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
2146  mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
2147 
2148  if ( !(nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
2149  nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1) ) // +1 because it touches next cells left/top
2150  return;
2151 
2152  tools::Long nMinX = nScrX;
2153  tools::Long nMinY = nScrY;
2154  tools::Long nMaxX = nScrX+nScrW-1;
2155  tools::Long nMaxY = nScrY+nScrH-1;
2156  if ( bLayoutRTL )
2157  {
2158  tools::Long nTemp = nMinX;
2159  nMinX = nMaxX;
2160  nMaxX = nTemp;
2161  }
2162  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2163 
2164  bool bTop = false;
2165  bool bBottom = false;
2166  bool bLeft = false;
2167  bool bRight = false;
2168 
2169  tools::Long nPosY = nScrY;
2170  bool bNoStartY = ( nY1 < nRefStartY );
2171  bool bNoEndY = false;
2172  for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
2173  {
2174  SCROW nY = pRowInfo[nArrY].nRowNo;
2175 
2176  if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2177  {
2178  nMinY = nPosY - 1;
2179  bTop = true;
2180  }
2181  if ( nY==nRefEndY )
2182  {
2183  nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
2184  bBottom = true;
2185  }
2186  if ( nY>nRefEndY && bNoEndY )
2187  {
2188  nMaxY = nPosY - 1;
2189  bBottom = true;
2190  }
2191  bNoStartY = ( nY < nRefStartY );
2192  bNoEndY = ( nY < nRefEndY );
2193  nPosY += pRowInfo[nArrY].nHeight;
2194  }
2195 
2196  tools::Long nPosX = nScrX;
2197  if ( bLayoutRTL )
2198  nPosX += nMirrorW - 1; // always in pixels
2199 
2200  for (SCCOL nX=nX1; nX<=nX2+1; nX++)
2201  {
2202  if ( nX==nRefStartX )
2203  {
2204  nMinX = nPosX - nLayoutSign;
2205  bLeft = true;
2206  }
2207  if ( nX==nRefEndX )
2208  {
2209  nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * nLayoutSign;
2210  bRight = true;
2211  }
2212  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2213  }
2214 
2215  if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
2216  return;
2217 
2218  if ( nType == SC_CAT_DELETE_ROWS )
2219  bLeft = bRight = bBottom = false;
2220  else if ( nType == SC_CAT_DELETE_COLS )
2221  bTop = bBottom = bRight = false;
2222 
2223  mpDev->SetLineColor( rColor );
2224  if (bTop && bBottom && bLeft && bRight)
2225  {
2226  mpDev->SetFillColor();
2227  mpDev->DrawRect( tools::Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2228  }
2229  else
2230  {
2231  if (bTop)
2232  {
2233  mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
2234  if ( nType == SC_CAT_DELETE_ROWS )
2235  mpDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
2236  }
2237  if (bBottom)
2238  mpDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
2239  if (bLeft)
2240  {
2241  mpDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
2242  if ( nType == SC_CAT_DELETE_COLS )
2243  mpDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
2244  }
2245  if (bRight)
2246  mpDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
2247  }
2248  if ( bLeft && bTop )
2249  {
2250  mpDev->SetLineColor();
2251  mpDev->SetFillColor( rColor );
2252  mpDev->DrawRect( tools::Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
2253  }
2254 }
2255 
2257 {
2258  ScChangeTrack* pTrack = mpDoc->GetChangeTrack();
2260  if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
2261  return; // nothing there or hidden
2262 
2263  ScActionColorChanger aColorChanger(*pTrack);
2264 
2265  // clipping happens from the outside
2267 
2268  SCCOL nEndX = nX2;
2269  SCROW nEndY = nY2;
2270  if ( nEndX < mpDoc->MaxCol() ) ++nEndX; // also from the next cell since the mark
2271  if ( nEndY < mpDoc->MaxRow() ) ++nEndY; // protrudes from the preceding cell
2272  ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
2273  const ScChangeAction* pAction = pTrack->GetFirst();
2274  while (pAction)
2275  {
2276  if ( pAction->IsVisible() )
2277  {
2278  ScChangeActionType eActionType = pAction->GetType();
2279  const ScBigRange& rBig = pAction->GetBigRange();
2280  if ( rBig.aStart.Tab() == nTab )
2281  {
2282  ScRange aRange = rBig.MakeRange();
2283 
2284  if ( eActionType == SC_CAT_DELETE_ROWS )
2285  aRange.aEnd.SetRow( aRange.aStart.Row() );
2286  else if ( eActionType == SC_CAT_DELETE_COLS )
2287  aRange.aEnd.SetCol( aRange.aStart.Col() );
2288 
2289  if ( aRange.Intersects( aViewRange ) &&
2290  ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2291  {
2292  aColorChanger.Update( *pAction );
2293  Color aColor( aColorChanger.GetColor() );
2294  DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2295  aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2296 
2297  }
2298  }
2299  if ( eActionType == SC_CAT_MOVE &&
2300  static_cast<const ScChangeActionMove*>(pAction)->
2301  GetFromRange().aStart.Tab() == nTab )
2302  {
2303  ScRange aRange = static_cast<const ScChangeActionMove*>(pAction)->
2304  GetFromRange().MakeRange();
2305  if ( aRange.Intersects( aViewRange ) &&
2306  ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2307  {
2308  aColorChanger.Update( *pAction );
2309  Color aColor( aColorChanger.GetColor() );
2310  DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2311  aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2312  }
2313  }
2314  }
2315 
2316  pAction = pAction->GetNext();
2317  }
2318 }
2319 
2320 //TODO: moggi Need to check if this can't be written simpler
2322 {
2323 
2324  bool bFirst = true;
2325 
2326  tools::Long nInitPosX = nScrX;
2327  if ( bLayoutRTL )
2328  nInitPosX += nMirrorW - 1; // always in pixels
2329  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2330 
2331  tools::Long nPosY = nScrY;
2332  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2333  {
2334  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2335  if ( pThisRowInfo->bChanged )
2336  {
2337  tools::Long nPosX = nInitPosX;
2338  for (SCCOL nX=nX1; nX<=nX2; nX++)
2339  {
2340  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2341  bool bIsMerged = false;
2342 
2343  if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2344  {
2345  // find start of merged cell
2346  bIsMerged = true;
2347  SCROW nY = pRowInfo[nArrY].nRowNo;
2348  SCCOL nMergeX = nX;
2349  SCROW nMergeY = nY;
2350  mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2351  // use origin's pCell for NotePtr test below
2352  }
2353 
2354  if ( mpDoc->GetNote(nX, pRowInfo[nArrY].nRowNo, nTab) && ( bIsMerged ||
2355  ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2356  {
2357  if (bFirst)
2358  {
2359  rRenderContext.SetLineColor(COL_WHITE);
2360 
2361  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2362  if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2363  rRenderContext.SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2364  else
2365  rRenderContext.SetFillColor(COL_LIGHTRED);
2366 
2367  bFirst = false;
2368  }
2369 
2370  tools::Long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
2371  if ( bIsMerged || pInfo->bMerged )
2372  {
2373  // if merged, add widths of all cells
2374  SCCOL nNextX = nX + 1;
2375  while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2376  {
2377  nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2378  ++nNextX;
2379  }
2380  }
2381  if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2382  rRenderContext.DrawRect( tools::Rectangle( nMarkX-5*nLayoutSign,nPosY,nMarkX+1*nLayoutSign,nPosY+6 ) );
2383  }
2384 
2385  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2386  }
2387  }
2388  nPosY += pThisRowInfo->nHeight;
2389  }
2390 }
2391 
2393 {
2394  vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >( mpDev->GetExtOutDevData() );
2395  if ( !pPDFData || !pPDFData->GetIsExportNotes() )
2396  return;
2397 
2398  tools::Long nInitPosX = nScrX;
2399  if ( bLayoutRTL )
2400  {
2401  Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
2402  tools::Long nOneX = aOnePixel.Width();
2403  nInitPosX += nMirrorW - nOneX;
2404  }
2405  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2406 
2407  tools::Long nPosY = nScrY;
2408  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2409  {
2410  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2411  if ( pThisRowInfo->bChanged )
2412  {
2413  tools::Long nPosX = nInitPosX;
2414  for (SCCOL nX=nX1; nX<=nX2; nX++)
2415  {
2416  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2417  bool bIsMerged = false;
2418  SCROW nY = pRowInfo[nArrY].nRowNo;
2419  SCCOL nMergeX = nX;
2420  SCROW nMergeY = nY;
2421 
2422  if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2423  {
2424  // find start of merged cell
2425  bIsMerged = true;
2426  mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2427  // use origin's pCell for NotePtr test below
2428  }
2429 
2430  if ( mpDoc->GetNote(nMergeX, nMergeY, nTab) && ( bIsMerged ||
2431  ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2432  {
2433  tools::Long nNoteWidth = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2434  tools::Long nNoteHeight = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTY );
2435 
2436  tools::Long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
2437  if ( bIsMerged || pInfo->bMerged )
2438  {
2439  // if merged, add widths of all cells
2440  SCCOL nNextX = nX + 1;
2441  while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2442  {
2443  nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2444  ++nNextX;
2445  }
2446  }
2447  if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2448  {
2449  tools::Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
2450  const ScPostIt* pNote = mpDoc->GetNote(nMergeX, nMergeY, nTab);
2451 
2452  // Note title is the cell address (as on printed note pages)
2453  ScAddress aAddress( nMergeX, nMergeY, nTab );
2454  OUString aTitle(aAddress.Format(ScRefFlags::VALID, mpDoc, mpDoc->GetAddressConvention()));
2455 
2456  // Content has to be a simple string without line breaks
2457  OUString aContent = pNote->GetText();
2458  aContent = aContent.replaceAll("\n", " ");
2459 
2460  vcl::PDFNote aNote;
2461  aNote.Title = aTitle;
2462  aNote.Contents = aContent;
2463  pPDFData->CreateNote( aNoteRect, aNote );
2464  }
2465  }
2466 
2467  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2468  }
2469  }
2470  nPosY += pThisRowInfo->nHeight;
2471  }
2472 }
2473 
2475 {
2476  if (!bAnyClipped)
2477  return;
2478 
2479  Color aArrowFillCol( COL_LIGHTRED );
2480 
2481  DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
2482  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2483  if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2484  {
2485  // use DrawMode to change the arrow's outline color
2486  mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine );
2487  // use text color also for the fill color
2488  aArrowFillCol = SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
2489  }
2490 
2491  tools::Long nInitPosX = nScrX;
2492  if ( bLayoutRTL )
2493  nInitPosX += nMirrorW - 1; // always in pixels
2494  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2495 
2496  tools::Rectangle aCellRect;
2497  tools::Long nPosY = nScrY;
2498  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2499  {
2500  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2501  if ( pThisRowInfo->bChanged )
2502  {
2503  SCROW nY = pThisRowInfo->nRowNo;
2504  tools::Long nPosX = nInitPosX;
2505  for (SCCOL nX=nX1; nX<=nX2; nX++)
2506  {
2507  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2508  if (pInfo->nClipMark != ScClipMark::NONE)
2509  {
2510  if (pInfo->bHOverlapped || pInfo->bVOverlapped)
2511  {
2512  // merge origin may be outside of visible area - use document functions
2513 
2514  SCCOL nOverX = nX;
2515  SCROW nOverY = nY;
2516  tools::Long nStartPosX = nPosX;
2517  tools::Long nStartPosY = nPosY;
2518 
2519  while ( nOverX > 0 && ( mpDoc->GetAttr(
2520  nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Hor ) )
2521  {
2522  --nOverX;
2523  nStartPosX -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2524  }
2525 
2526  while ( nOverY > 0 && ( mpDoc->GetAttr(
2527  nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Ver ) )
2528  {
2529  --nOverY;
2530  nStartPosY -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2531  }
2532 
2533  tools::Long nOutWidth = static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2534  tools::Long nOutHeight = static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2535 
2536  const ScMergeAttr* pMerge = mpDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
2537  SCCOL nCountX = pMerge->GetColMerge();
2538  for (SCCOL i=1; i<nCountX; i++)
2539  nOutWidth += static_cast<tools::Long>( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
2540  SCROW nCountY = pMerge->GetRowMerge();
2541  nOutHeight += static_cast<tools::Long>(mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY));
2542 
2543  if ( bLayoutRTL )
2544  nStartPosX -= nOutWidth - 1;
2545  aCellRect = tools::Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
2546  }
2547  else
2548  {
2549  tools::Long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
2550  tools::Long nOutHeight = pThisRowInfo->nHeight;
2551 
2552  if ( pInfo->bMerged && pInfo->pPatternAttr )
2553  {
2554  SCCOL nOverX = nX;
2555  SCROW nOverY = nY;
2556  const ScMergeAttr* pMerge =
2557  &pInfo->pPatternAttr->GetItem(ATTR_MERGE);
2558  SCCOL nCountX = pMerge->GetColMerge();
2559  for (SCCOL i=1; i<nCountX; i++)
2560  nOutWidth += static_cast<tools::Long>( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
2561  SCROW nCountY = pMerge->GetRowMerge();
2562  nOutHeight += static_cast<tools::Long>(mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY));
2563  }
2564 
2565  tools::Long nStartPosX = nPosX;
2566  if ( bLayoutRTL )
2567  nStartPosX -= nOutWidth - 1;
2568  // #i80447# create aCellRect from two points in case nOutWidth is 0
2569  aCellRect = tools::Rectangle( Point( nStartPosX, nPosY ),
2570  Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
2571  }
2572 
2573  aCellRect.AdjustBottom( -1 ); // don't paint over the cell grid
2574  if ( bLayoutRTL )
2575  aCellRect.AdjustLeft(1 );
2576  else
2577  aCellRect.AdjustRight( -1 );
2578 
2579  tools::Long nMarkPixel = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2580  Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
2581 
2582  if (bVertical)
2583  {
2585  {
2586  // visually top
2587  tools::Rectangle aMarkRect = aCellRect;
2588  aMarkRect.SetBottom(aCellRect.Top() + nMarkPixel - 1);
2589  SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true, true);
2590  }
2591  if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Top : ScClipMark::Bottom))
2592  {
2593  // visually bottom
2594  tools::Rectangle aMarkRect = aCellRect;
2595  aMarkRect.SetTop(aCellRect.Bottom() + nMarkPixel + 1);
2596  SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
2597  true);
2598  }
2599  }
2600  else
2601  {
2603  {
2604  // visually left
2605  tools::Rectangle aMarkRect = aCellRect;
2606  aMarkRect.SetRight(aCellRect.Left() + nMarkPixel - 1);
2607  SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true,
2608  false);
2609  }
2610  if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Left : ScClipMark::Right))
2611  {
2612  // visually right
2613  tools::Rectangle aMarkRect = aCellRect;
2614  aMarkRect.SetLeft(aCellRect.Right() - nMarkPixel + 1);
2615  SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
2616  false);
2617  }
2618  }
2619  }
2620  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2621  }
2622  }
2623  nPosY += pThisRowInfo->nHeight;
2624  }
2625 
2626  mpDev->SetDrawMode(nOldDrawMode);
2627 }
2628 
2629 /* 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:2131
SCCOL GetColMerge() const
Definition: attrib.hxx:68
bool IsDataValid(const OUString &rTest, const ScPatternAttr &rPattern, const ScAddress &rPos) const
Definition: validat.cxx:527
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:1328
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:1914
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:2474
std::unique_ptr< ContentProperties > pData
bool bLayoutRTL
Definition: output.hxx:236
bool IsTransparent() const
bool mbUseStyleColor
Definition: output.hxx:216
constexpr tools::Long Left() const
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:1387
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()
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
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:2011
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:2256
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
SCROW nRowNo
Definition: fillinfo.hxx:181
ReferenceMark FillReferenceMark(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor)
Definition: output.cxx:1919
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:882
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
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:161
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
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:2405
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
constexpr void SetLeft(tools::Long v)
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:1774
const SdrPage * GetPage(sal_uInt16 nPgNum) const
const ScRange & GetPrintRange() const
Definition: pagedata.hxx:44
void SetXOffset(tools::Long nXOffset)
constexpr tools::Long Right() const
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
constexpr tools::Long Top() 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
bool IsFullyTransparent() const
constexpr void SetRight(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
constexpr void SetBottom(tools::Long v)
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
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
Definition: documen4.cxx:799
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
constexpr void SetTop(tools::Long v)
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:1314
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:2138
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
constexpr tools::Long Bottom() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
ScBreakType
Definition: global.hxx:149
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:599
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:142
ScChangeViewSettings * GetChangeViewSettings() const
Definition: document.hxx:2166
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:398
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:2321
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:986
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:1732
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:2392
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 DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
basegfx::B2DHomMatrix GetViewTransformation() const
void FindChanged()
Definition: output.cxx:1815
bool IsIdleEnabled() const
Definition: document.hxx:2130
const SvxShadowItem * pHShadowOrigin
Definition: fillinfo.hxx:148
ScTableInfo & mrTabInfo
Definition: output.hxx:179
DrawModeFlags
const Color & GetWindowTextColor() 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