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