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