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, tools::Long nNewScrX, tools::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  tools::Long nPosX;
294  tools::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  tools::Long nOneX = 1;
341  tools::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  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
350  tools::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 tools::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 tools::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 tools::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  tools::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  tools::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, tools::Long nOneX, tools::Long nOneY)
825 {
826  tools::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  tools::Long nLength = aPaintRect.Right() - aPaintRect.Left();
836  nPosZero = static_cast<tools::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  tools::Long nLength = nPosZero - aPaintRect.Left();
847  aPaintRect.SetLeft( nPosZero + static_cast<tools::Long>(nLength * pOldDataBarInfo->mnLength/100.0) );
848  }
849  else if(pOldDataBarInfo->mnLength > 0)
850  {
851  aPaintRect.SetLeft( nPosZero );
852  tools::Long nLength = aPaintRect.Right() - nPosZero;
853  aPaintRect.SetRight( nPosZero + static_cast<tools::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(Degree10(2700));
866  else
867  aGradient.SetAngle(Degree10(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  return;
882 
883  Point aPoint1(nPosZero, rRect.Top());
884  Point aPoint2(nPosZero, rRect.Bottom());
885  LineInfo aLineInfo(LineStyle::Dash, 1);
886  aLineInfo.SetDashCount( 4 );
887  aLineInfo.SetDistance( 3 );
888  aLineInfo.SetDashLen( 3 );
889  rRenderContext.SetFillColor(pOldDataBarInfo->maAxisColor);
890  rRenderContext.SetLineColor(pOldDataBarInfo->maAxisColor);
891  rRenderContext.DrawLine(aPoint1, aPoint2, aLineInfo);
892  rRenderContext.SetLineColor();
893  rRenderContext.SetFillColor();
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, tools::Long nOneX, tools::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  tools::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, tools::Long nPosX, tools::Long nLayoutSign, tools::Long nOneX, tools::Long nOneY, const ScDataBarInfo* pDataBarInfo, const ScDataBarInfo*& pOldDataBarInfo,
914  const ScIconSetInfo* pIconSetInfo, const ScIconSetInfo*& pOldIconSetInfo,
915  sc::IconSetBitmapMap & rIconSetBitmapMap)
916 {
917  tools::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  tools::Long nOneXLogic = aOnePixel.Width();
994  tools::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  tools::Long nOneX = 1;
1002  tools::Long nOneY = 1;
1003  if (!bWorksInPixels)
1004  {
1005  nOneX = nOneXLogic;
1006  nOneY = nOneYLogic;
1007  }
1008 
1009  tools::Rectangle aRect;
1010 
1011  tools::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  tools::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  tools::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  tools::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  tools::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  tools::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  tools::Long nInitPosX = nScrX;
1164  if ( bLayoutRTL )
1165  {
1166  Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
1167  tools::Long nOneX = aOnePixel.Width();
1168  nInitPosX += nMirrorW - nOneX;
1169  }
1170  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1171 
1172  tools::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  tools::Long nRowHeight = pThisRowInfo->nHeight;
1180 
1181  if ( pThisRowInfo->bChanged && !bSkipY )
1182  {
1183  tools::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  tools::Long nThisWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
1208  tools::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  tools::Long nSize = pAttr->GetWidth();
1224  tools::Long nSizeX = static_cast<tools::Long>(nSize*mnPPTX);
1225  if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
1226  tools::Long nSizeY = static_cast<tools::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  tools::Long nOneX = aOnePixel.Width();
1299  tools::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  tools::Long nPosY = nScrY;
1312  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1313  {
1314  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1315  tools::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 tools::Long lclGetSnappedX( const OutputDevice& rDev, tools::Long nPosX, bool bSnapPixel )
1340 {
1341  return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
1342 }
1343 
1344 static tools::Long lclGetSnappedY( const OutputDevice& rDev, tools::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  tools::Long nInitPosX = nScrX;
1394  if ( bLayoutRTL )
1395  {
1396  Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
1397  tools::Long nOneX = aOnePixel.Width();
1398  nInitPosX += nMirrorW - nOneX;
1399  }
1400  tools::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  tools::Long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
1413  tools::Long nOldSnapY = lclGetSnappedY( rRenderContext, nOldPosY, bSnapPixel );
1414  rArray.SetYOffset( nOldSnapY );
1415  for( size_t nRow = 0; nRow < nRowCount; ++nRow )
1416  {
1417  tools::Long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
1418  tools::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  tools::Long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].pCellInfo[ nX1 ].nWidth);
1429  tools::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  tools::Long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx ].nWidth * nLayoutSign;
1437  tools::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  tools::Long nInitPosX = nScrX;
1495  if ( bLayoutRTL )
1496  {
1497  Size aOnePixel = rRenderContext.PixelToLogic(Size(1,1));
1498  tools::Long nOneX = aOnePixel.Width();
1499  nInitPosX += nMirrorW - nOneX;
1500  }
1501  tools::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  tools::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  tools::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  tools::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  tools::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  tools::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<tools::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  tools::Long nTop = nPosY - 1;
1574  tools::Long nBottom = nPosY + nRowHeight - 1;
1575  tools::Long nTopLeft = nPosX - nLayoutSign;
1576  tools::Long nTopRight = nPosX + (nColWidth - 1) * nLayoutSign;
1577  tools::Long nBotLeft = nTopLeft;
1578  tools::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  tools::Long nSkew = static_cast<tools::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  tools::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  tools::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  tools::Long nMinX = nScrX;
1897  tools::Long nMinY = nScrY;
1898  tools::Long nMaxX = nScrX + nScrW - 1;
1899  tools::Long nMaxY = nScrY + nScrH - 1;
1900  if ( bLayoutRTL )
1901  {
1902  tools::Long nTemp = nMinX;
1903  nMinX = nMaxX;
1904  nMaxX = nTemp;
1905  }
1906  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1907 
1908  bool bTop = false;
1909  bool bBottom = false;
1910  bool bLeft = false;
1911  bool bRight = false;
1912 
1913  tools::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  tools::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  return;
1987 
1988  tools::Long nMinX = nScrX;
1989  tools::Long nMinY = nScrY;
1990  tools::Long nMaxX = nScrX + nScrW - 1;
1991  tools::Long nMaxY = nScrY + nScrH - 1;
1992  if ( bLayoutRTL )
1993  {
1994  tools::Long nTemp = nMinX;
1995  nMinX = nMaxX;
1996  nMaxX = nTemp;
1997  }
1998  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1999 
2000  bool bTop = false;
2001  bool bBottom = false;
2002  bool bLeft = false;
2003  bool bRight = false;
2004 
2005  tools::Long nPosY = nScrY;
2006  bool bNoStartY = ( nY1 < nRefStartY );
2007  bool bNoEndY = false;
2008  for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
2009  {
2010  SCROW nY = pRowInfo[nArrY].nRowNo;
2011 
2012  if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2013  {
2014  nMinY = nPosY;
2015  bTop = true;
2016  }
2017  if ( nY==nRefEndY )
2018  {
2019  nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
2020  bBottom = true;
2021  }
2022  if ( nY>nRefEndY && bNoEndY )
2023  {
2024  nMaxY = nPosY-2;
2025  bBottom = true;
2026  }
2027  bNoStartY = ( nY < nRefStartY );
2028  bNoEndY = ( nY < nRefEndY );
2029  nPosY += pRowInfo[nArrY].nHeight;
2030  }
2031 
2032  tools::Long nPosX = nScrX;
2033  if ( bLayoutRTL )
2034  nPosX += nMirrorW - 1; // always in pixels
2035 
2036  for (SCCOL nX=nX1; nX<=nX2; nX++)
2037  {
2038  if ( nX==nRefStartX )
2039  {
2040  nMinX = nPosX;
2041  bLeft = true;
2042  }
2043  if ( nX==nRefEndX )
2044  {
2045  nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
2046  bRight = true;
2047  }
2048  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2049  }
2050 
2051  if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
2052  return;
2053 
2054  mpDev->SetLineColor( rColor );
2055  if (bTop && bBottom && bLeft && bRight && !comphelper::LibreOfficeKit::isActive() )
2056  {
2057  mpDev->SetFillColor();
2058  mpDev->DrawRect( tools::Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2059  }
2061  {
2062  if (bTop)
2063  mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMaxX, nMinY ) );
2064  if (bBottom)
2065  mpDev->DrawLine( Point( nMinX, nMaxY ), Point( nMaxX, nMaxY ) );
2066  if (bLeft)
2067  mpDev->DrawLine( Point( nMinX, nMinY ), Point( nMinX, nMaxY ) );
2068  if (bRight)
2069  mpDev->DrawLine( Point( nMaxX, nMinY ), Point( nMaxX, nMaxY ) );
2070  }
2071  if ( !bHandle || !bRight || !bBottom || comphelper::LibreOfficeKit::isActive() )
2072  return;
2073 
2074  mpDev->SetLineColor( rColor );
2075  mpDev->SetFillColor( rColor );
2076 
2077  const sal_Int32 aRadius = 4;
2078 
2079  sal_Int32 aRectMaxX1 = nMaxX - nLayoutSign * aRadius;
2080  sal_Int32 aRectMaxX2 = nMaxX + nLayoutSign;
2081  sal_Int32 aRectMinX1 = nMinX - nLayoutSign;
2082  sal_Int32 aRectMinX2 = nMinX + nLayoutSign * aRadius;
2083 
2084  sal_Int32 aRectMaxY1 = nMaxY - aRadius;
2085  sal_Int32 aRectMaxY2 = nMaxY + 1;
2086  sal_Int32 aRectMinY1 = nMinY - 1;
2087  sal_Int32 aRectMinY2 = nMinY + aRadius;
2088 
2089  // Draw corner rectangles
2090  tools::Rectangle aLowerRight( aRectMaxX1, aRectMaxY1, aRectMaxX2, aRectMaxY2 );
2091  tools::Rectangle aUpperLeft ( aRectMinX1, aRectMinY1, aRectMinX2, aRectMinY2 );
2092  tools::Rectangle aLowerLeft ( aRectMinX1, aRectMaxY1, aRectMinX2, aRectMaxY2 );
2093  tools::Rectangle aUpperRight( aRectMaxX1, aRectMinY1, aRectMaxX2, aRectMinY2 );
2094 
2095  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerRight ) ), lclCornerRectTransparency );
2096  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperLeft ) ), lclCornerRectTransparency );
2097  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aLowerLeft ) ), lclCornerRectTransparency );
2098  mpDev->DrawTransparent( tools::PolyPolygon( tools::Polygon( aUpperRight ) ), lclCornerRectTransparency );
2099 }
2100 
2101 void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
2102  SCCOL nRefEndX, SCROW nRefEndY,
2103  const Color& rColor, sal_uInt16 nType )
2104 {
2105  PutInOrder( nRefStartX, nRefEndX );
2106  PutInOrder( nRefStartY, nRefEndY );
2107 
2108  if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
2109  mpDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
2110 
2111  if ( !(nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
2112  nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1) ) // +1 because it touches next cells left/top
2113  return;
2114 
2115  tools::Long nMinX = nScrX;
2116  tools::Long nMinY = nScrY;
2117  tools::Long nMaxX = nScrX+nScrW-1;
2118  tools::Long nMaxY = nScrY+nScrH-1;
2119  if ( bLayoutRTL )
2120  {
2121  tools::Long nTemp = nMinX;
2122  nMinX = nMaxX;
2123  nMaxX = nTemp;
2124  }
2125  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2126 
2127  bool bTop = false;
2128  bool bBottom = false;
2129  bool bLeft = false;
2130  bool bRight = false;
2131 
2132  tools::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  tools::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 || nMaxY < nMinY )
2179  return;
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 
2220 {
2221  ScChangeTrack* pTrack = mpDoc->GetChangeTrack();
2223  if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
2224  return; // nothing there or hidden
2225 
2226  ScActionColorChanger aColorChanger(*pTrack);
2227 
2228  // clipping happens from the outside
2230 
2231  SCCOL nEndX = nX2;
2232  SCROW nEndY = nY2;
2233  if ( nEndX < mpDoc->MaxCol() ) ++nEndX; // also from the next cell since the mark
2234  if ( nEndY < mpDoc->MaxRow() ) ++nEndY; // protrudes from the preceding cell
2235  ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
2236  const ScChangeAction* pAction = pTrack->GetFirst();
2237  while (pAction)
2238  {
2239  if ( pAction->IsVisible() )
2240  {
2241  ScChangeActionType eActionType = pAction->GetType();
2242  const ScBigRange& rBig = pAction->GetBigRange();
2243  if ( rBig.aStart.Tab() == nTab )
2244  {
2245  ScRange aRange = rBig.MakeRange();
2246 
2247  if ( eActionType == SC_CAT_DELETE_ROWS )
2248  aRange.aEnd.SetRow( aRange.aStart.Row() );
2249  else if ( eActionType == SC_CAT_DELETE_COLS )
2250  aRange.aEnd.SetCol( aRange.aStart.Col() );
2251 
2252  if ( aRange.Intersects( aViewRange ) &&
2253  ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2254  {
2255  aColorChanger.Update( *pAction );
2256  Color aColor( aColorChanger.GetColor() );
2257  DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2258  aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2259 
2260  }
2261  }
2262  if ( eActionType == SC_CAT_MOVE &&
2263  static_cast<const ScChangeActionMove*>(pAction)->
2264  GetFromRange().aStart.Tab() == nTab )
2265  {
2266  ScRange aRange = static_cast<const ScChangeActionMove*>(pAction)->
2267  GetFromRange().MakeRange();
2268  if ( aRange.Intersects( aViewRange ) &&
2269  ScViewUtil::IsActionShown( *pAction, *pSettings, *mpDoc ) )
2270  {
2271  aColorChanger.Update( *pAction );
2272  Color aColor( aColorChanger.GetColor() );
2273  DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2274  aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2275  }
2276  }
2277  }
2278 
2279  pAction = pAction->GetNext();
2280  }
2281 }
2282 
2283 //TODO: moggi Need to check if this can't be written simpler
2285 {
2286 
2287  bool bFirst = true;
2288 
2289  tools::Long nInitPosX = nScrX;
2290  if ( bLayoutRTL )
2291  nInitPosX += nMirrorW - 1; // always in pixels
2292  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2293 
2294  tools::Long nPosY = nScrY;
2295  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2296  {
2297  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2298  if ( pThisRowInfo->bChanged )
2299  {
2300  tools::Long nPosX = nInitPosX;
2301  for (SCCOL nX=nX1; nX<=nX2; nX++)
2302  {
2303  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2304  bool bIsMerged = false;
2305 
2306  if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2307  {
2308  // find start of merged cell
2309  bIsMerged = true;
2310  SCROW nY = pRowInfo[nArrY].nRowNo;
2311  SCCOL nMergeX = nX;
2312  SCROW nMergeY = nY;
2313  mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2314  // use origin's pCell for NotePtr test below
2315  }
2316 
2317  if ( mpDoc->GetNote(nX, pRowInfo[nArrY].nRowNo, nTab) && ( bIsMerged ||
2318  ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2319  {
2320  if (bFirst)
2321  {
2322  rRenderContext.SetLineColor(COL_WHITE);
2323 
2324  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2325  if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2326  rRenderContext.SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2327  else
2328  rRenderContext.SetFillColor(COL_LIGHTRED);
2329 
2330  bFirst = false;
2331  }
2332 
2333  tools::Long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
2334  if ( bIsMerged || pInfo->bMerged )
2335  {
2336  // if merged, add widths of all cells
2337  SCCOL nNextX = nX + 1;
2338  while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2339  {
2340  nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2341  ++nNextX;
2342  }
2343  }
2344  if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2345  rRenderContext.DrawRect( tools::Rectangle( nMarkX-5*nLayoutSign,nPosY,nMarkX+1*nLayoutSign,nPosY+6 ) );
2346  }
2347 
2348  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2349  }
2350  }
2351  nPosY += pThisRowInfo->nHeight;
2352  }
2353 }
2354 
2356 {
2357  vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >( mpDev->GetExtOutDevData() );
2358  if ( !pPDFData || !pPDFData->GetIsExportNotes() )
2359  return;
2360 
2361  tools::Long nInitPosX = nScrX;
2362  if ( bLayoutRTL )
2363  {
2364  Size aOnePixel = mpDev->PixelToLogic(Size(1,1));
2365  tools::Long nOneX = aOnePixel.Width();
2366  nInitPosX += nMirrorW - nOneX;
2367  }
2368  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2369 
2370  tools::Long nPosY = nScrY;
2371  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2372  {
2373  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2374  if ( pThisRowInfo->bChanged )
2375  {
2376  tools::Long nPosX = nInitPosX;
2377  for (SCCOL nX=nX1; nX<=nX2; nX++)
2378  {
2379  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2380  bool bIsMerged = false;
2381  SCROW nY = pRowInfo[nArrY].nRowNo;
2382  SCCOL nMergeX = nX;
2383  SCROW nMergeY = nY;
2384 
2385  if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2386  {
2387  // find start of merged cell
2388  bIsMerged = true;
2389  mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2390  // use origin's pCell for NotePtr test below
2391  }
2392 
2393  if ( mpDoc->GetNote(nMergeX, nMergeY, nTab) && ( bIsMerged ||
2394  ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2395  {
2396  tools::Long nNoteWidth = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2397  tools::Long nNoteHeight = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTY );
2398 
2399  tools::Long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
2400  if ( bIsMerged || pInfo->bMerged )
2401  {
2402  // if merged, add widths of all cells
2403  SCCOL nNextX = nX + 1;
2404  while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2405  {
2406  nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2407  ++nNextX;
2408  }
2409  }
2410  if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2411  {
2412  tools::Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
2413  const ScPostIt* pNote = mpDoc->GetNote(nMergeX, nMergeY, nTab);
2414 
2415  // Note title is the cell address (as on printed note pages)
2416  ScAddress aAddress( nMergeX, nMergeY, nTab );
2417  OUString aTitle(aAddress.Format(ScRefFlags::VALID, mpDoc, mpDoc->GetAddressConvention()));
2418 
2419  // Content has to be a simple string without line breaks
2420  OUString aContent = pNote->GetText();
2421  aContent = aContent.replaceAll("\n", " ");
2422 
2423  vcl::PDFNote aNote;
2424  aNote.Title = aTitle;
2425  aNote.Contents = aContent;
2426  pPDFData->CreateNote( aNoteRect, aNote );
2427  }
2428  }
2429 
2430  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2431  }
2432  }
2433  nPosY += pThisRowInfo->nHeight;
2434  }
2435 }
2436 
2438 {
2439  if (!bAnyClipped)
2440  return;
2441 
2442  Color aArrowFillCol( COL_LIGHTRED );
2443 
2444  DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
2445  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2446  if ( mbUseStyleColor && rStyleSettings.GetHighContrastMode() )
2447  {
2448  // use DrawMode to change the arrow's outline color
2449  mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine );
2450  // use text color also for the fill color
2451  aArrowFillCol = SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
2452  }
2453 
2454  tools::Long nInitPosX = nScrX;
2455  if ( bLayoutRTL )
2456  nInitPosX += nMirrorW - 1; // always in pixels
2457  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2458 
2459  tools::Rectangle aCellRect;
2460  tools::Long nPosY = nScrY;
2461  for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2462  {
2463  RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2464  if ( pThisRowInfo->bChanged )
2465  {
2466  SCROW nY = pThisRowInfo->nRowNo;
2467  tools::Long nPosX = nInitPosX;
2468  for (SCCOL nX=nX1; nX<=nX2; nX++)
2469  {
2470  CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2471  if (pInfo->nClipMark != ScClipMark::NONE)
2472  {
2473  if (pInfo->bHOverlapped || pInfo->bVOverlapped)
2474  {
2475  // merge origin may be outside of visible area - use document functions
2476 
2477  SCCOL nOverX = nX;
2478  SCROW nOverY = nY;
2479  tools::Long nStartPosX = nPosX;
2480  tools::Long nStartPosY = nPosY;
2481 
2482  while ( nOverX > 0 && ( mpDoc->GetAttr(
2483  nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Hor ) )
2484  {
2485  --nOverX;
2486  nStartPosX -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2487  }
2488 
2489  while ( nOverY > 0 && ( mpDoc->GetAttr(
2490  nOverX, nOverY, nTab, ATTR_MERGE_FLAG )->GetValue() & ScMF::Ver ) )
2491  {
2492  --nOverY;
2493  nStartPosY -= nLayoutSign * static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2494  }
2495 
2496  tools::Long nOutWidth = static_cast<tools::Long>( mpDoc->GetColWidth(nOverX,nTab) * mnPPTX );
2497  tools::Long nOutHeight = static_cast<tools::Long>( mpDoc->GetRowHeight(nOverY,nTab) * mnPPTY );
2498 
2499  const ScMergeAttr* pMerge = mpDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
2500  SCCOL nCountX = pMerge->GetColMerge();
2501  for (SCCOL i=1; i<nCountX; i++)
2502  nOutWidth += static_cast<tools::Long>( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
2503  SCROW nCountY = pMerge->GetRowMerge();
2504  nOutHeight += static_cast<tools::Long>(mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY));
2505 
2506  if ( bLayoutRTL )
2507  nStartPosX -= nOutWidth - 1;
2508  aCellRect = tools::Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
2509  }
2510  else
2511  {
2512  tools::Long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
2513  tools::Long nOutHeight = pThisRowInfo->nHeight;
2514 
2515  if ( pInfo->bMerged && pInfo->pPatternAttr )
2516  {
2517  SCCOL nOverX = nX;
2518  SCROW nOverY = nY;
2519  const ScMergeAttr* pMerge =
2520  &pInfo->pPatternAttr->GetItem(ATTR_MERGE);
2521  SCCOL nCountX = pMerge->GetColMerge();
2522  for (SCCOL i=1; i<nCountX; i++)
2523  nOutWidth += static_cast<tools::Long>( mpDoc->GetColWidth(nOverX+i,nTab) * mnPPTX );
2524  SCROW nCountY = pMerge->GetRowMerge();
2525  nOutHeight += static_cast<tools::Long>(mpDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, mnPPTY));
2526  }
2527 
2528  tools::Long nStartPosX = nPosX;
2529  if ( bLayoutRTL )
2530  nStartPosX -= nOutWidth - 1;
2531  // #i80447# create aCellRect from two points in case nOutWidth is 0
2532  aCellRect = tools::Rectangle( Point( nStartPosX, nPosY ),
2533  Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
2534  }
2535 
2536  aCellRect.AdjustBottom( -1 ); // don't paint over the cell grid
2537  if ( bLayoutRTL )
2538  aCellRect.AdjustLeft(1 );
2539  else
2540  aCellRect.AdjustRight( -1 );
2541 
2542  tools::Long nMarkPixel = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
2543  Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
2544 
2545  if ( pInfo->nClipMark & ( bLayoutRTL ? ScClipMark::Right : ScClipMark::Left ) )
2546  {
2547  // visually left
2548  tools::Rectangle aMarkRect = aCellRect;
2549  aMarkRect.SetRight( aCellRect.Left()+nMarkPixel-1 );
2550  SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, true );
2551  }
2552  if ( pInfo->nClipMark & ( bLayoutRTL ? ScClipMark::Left : ScClipMark::Right ) )
2553  {
2554  // visually right
2555  tools::Rectangle aMarkRect = aCellRect;
2556  aMarkRect.SetLeft( aCellRect.Right()-nMarkPixel+1 );
2557  SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, false );
2558  }
2559  }
2560  nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2561  }
2562  }
2563  nPosY += pThisRowInfo->nHeight;
2564  }
2565 
2566  mpDev->SetDrawMode(nOldDrawMode);
2567 }
2568 
2569 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::Long nScrY
Definition: output.hxx:184
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
sal_uInt16 Count() const
void SetClipRegion()
const int nColCount
void SetSyntaxMode(bool bNewMode)
Definition: output.cxx:277
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:2107
const SCCOL SC_ROTMAX_NONE
Definition: fillinfo.hxx:171
void StripHidden(SCCOL &rX1, SCROW &rY1, SCCOL &rX2, SCROW &rY2, SCTAB nTab)
Definition: document.cxx:4700
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
void DrawFrame(vcl::RenderContext &rRenderContext)
Definition: output.cxx:1354
ScRotateDir
Definition: fillinfo.hxx:41
SC_DLLPUBLIC bool IsTabProtected(SCTAB nTab) const
Definition: documen3.cxx:1890
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
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTMAGENTA
SCROW Row() const
Definition: address.hxx:262
DrawModeFlags
ScChangeAction * GetNext() const
Definition: chgtrack.hxx:323
SvxRotateMode
void DrawClipMarks()
Definition: output.cxx:2437
bool bLayoutRTL
Definition: output.hxx:234
tools::Long GetRotateVal(const SfxItemSet *pCondSet) const
Definition: patattr.cxx:1315
bool mbUseStyleColor
Definition: output.hxx:215
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
void AddVerLine(bool bWorksInPixels, tools::Long nX, tools::Long nY1, tools::Long nY2, bool bDashed=false)
Definition: gridmerg.cxx:140
bool bSnapPixel
Definition: output.hxx: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
tools::Long getWidth() const
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1549
sc::IconSetBitmapMap & GetIconSetBitmapMap()
Definition: documen2.cxx:1383
bool GetDirty() const
SCCOL nEditCol
Definition: output.hxx:207
sal_uInt8 GetTransparency() const
#define SAL_INFO_IF(condition, area, stream)
long Long
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:2219
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)
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:489
CALCPAGEBREAKAUTOMATIC
void SetRight(tools::Long v)
SCROW nRowNo
Definition: fillinfo.hxx:182
ReferenceMark FillReferenceMark(SCCOL nRefStartX, SCROW nRefStartY, SCCOL nRefEndX, SCROW nRefEndY, const Color &rColor)
Definition: output.cxx:1882
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4359
Color maColor
Definition: fillinfo.hxx:66
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
void SetContentDevice(OutputDevice *pContentDev)
Definition: output.cxx:219
SCROW nY2
Definition: output.hxx:191
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:6508
bool ShowChanges() const
Definition: chgviset.hxx:78
SVXCORE_DLLPUBLIC css::uno::Reference< css::drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage)
SvxShadowLocation GetLocation() const
SCROW nVisY2
Definition: output.hxx:195
ScClipMark nClipMark
Definition: fillinfo.hxx:154
tools::Long Left() const
void SetLeft(tools::Long v)
std::unique_ptr< const ScDataBarInfo > pDataBar
Definition: fillinfo.hxx:138
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx: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
tools::Long Bottom() const
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:959
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
sal_uInt16 nHeight
Definition: fillinfo.hxx:181
ScAddress aPos
size_t GetCount() const
Definition: pagedata.hxx:74
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void DrawLine(const Point &rStartPt, const Point &rEndPt)
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4735
void SetCol(SCCOL nColP)
Definition: address.hxx:279
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTRED
bool IsChanged() const
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx: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:4714
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 AddHorLine(bool bWorksInPixels, tools::Long nX1, tools::Long nX2, tools::Long nY, bool bDashed=false)
Definition: gridmerg.cxx:96
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:954
double mnPPTY
Definition: output.hxx: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
tools::Long getHeight() const
Color GetTrackInsertColor() const
Definition: appoptio.hxx:62
const Color & GetColor() const
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:4445
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
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:4198
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 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:45
void SetFillColor()
tools::Long Width() const
bool mbSyntaxMode
Definition: output.hxx:218
void DrawBackground(vcl::RenderContext &rRenderContext)
Definition: output.cxx:990
void DrawDocumentBackground()
Definition: output.cxx:805
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
void SetTop(tools::Long v)
void SetBottom(tools::Long v)
bool IsRunning() const
SCSIZE nArrCount
Definition: output.hxx:180
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
ScOutputData(OutputDevice *pNewDev, ScOutputType eNewType, ScTableInfo &rTabInfo, ScDocument *pNewDoc, SCTAB nNewTab, tools::Long nNewScrX, tools::Long nNewScrY, SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2, double nPixelPerTwipsX, double nPixelPerTwipsY, const Fraction *pZoomX=nullptr, const Fraction *pZoomY=nullptr)
Definition: output.cxx:134
ScRefCellValue maCell
Definition: fillinfo.hxx:133
void Update(const ScChangeAction &rAction)
Definition: output.cxx:88
DrawModeFlags GetDrawMode() const
tools::Long Top() const
SC_DLLPUBLIC const SfxItemSet * GetCondResult(SCCOL nCol, SCROW nRow, SCTAB nTab, ScRefCellValue *pCell=nullptr) const
Definition: documen4.cxx:788
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5568
tools::Long nScrX
Definition: output.hxx:183
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:2101
SCTAB nTab
Definition: output.hxx:182
Color aGridColor
Definition: output.hxx:223
const SvxShadowItem * pVShadowOrigin
Definition: fillinfo.hxx:150
tools::Long AdjustTop(tools::Long nVertMoveDelta)
#define SC_AUTHORCOLORCOUNT
Definition: output.cxx:71
tools::Long nScrH
Definition: output.hxx:186
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
ScBreakType
Definition: global.hxx:150
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:594
static tools::Long lclGetSnappedY(const OutputDevice &rDev, tools::Long nPosY, bool bSnapPixel)
Definition: output.cxx:1344
static tools::Long lclGetSnappedX(const OutputDevice &rDev, tools::Long nPosX, bool bSnapPixel)
Definition: output.cxx:1339
ScShadowPart eHShadowPart
Definition: fillinfo.hxx:152
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
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
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const
Definition: document.cxx:4374
SCCOL nVisX2
Definition: output.hxx:194
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BROWN
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
#define F_PI18000
void SetSpellCheckContext(const sc::SpellCheckContext *pCxt)
Definition: output.cxx:214
tools::Long Height() const
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
bool bTabProtected
Definition: output.hxx:233
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
const std::set< OUString > & rUsers
Definition: chgtrack.hxx:52
void DrawNoteMarks(vcl::RenderContext &rRenderContext)
Definition: output.cxx:2284
CALCPAGEBREAKMANUAL
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:4429
const OUString & GetUser() const
Definition: chgtrack.hxx:352
sal_uInt16 nLastUserIndex
Definition: chgtrack.hxx:54
ScIconSetType
Definition: colorscale.hxx:189
VclPtr< OutputDevice > mpDev
Definition: output.hxx:175
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTBLUE
void SetMirrorWidth(tools::Long nNew)
Definition: output.cxx:230
CALCPROTECTEDBACKGROUND
void Flush()
Definition: gridmerg.cxx:184
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1058
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
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
tools::Long nScrW
Definition: output.hxx:185
void DrawShadow()
Definition: output.cxx:1148
void AddPDFNotes()
Definition: output.cxx:2355
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:5478
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4120
void Push(PushFlags nFlags=PushFlags::ALL)
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
tools::Long Right() const
bool bEditMode
Definition: output.hxx:206
bool bMerged
Definition: fillinfo.hxx:159
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
void SetPagebreakMode(ScPageBreakData *pPageData)
Definition: output.cxx:576
const SfxItemSet * pConditionSet
Definition: fillinfo.hxx:136
sal_uInt16 GetWidth() const
SvxShadowLocation
tools::Long nMirrorW
Definition: output.hxx:187