1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 // INCLUDE --------------------------------------------------------------- 28 29 #include "scitems.hxx" 30 #include <editeng/eeitem.hxx> 31 32 #include "printfun.hxx" 33 34 #include <svx/svxids.hrc> 35 #include <editeng/adjitem.hxx> 36 #include <editeng/boxitem.hxx> 37 #include <editeng/brshitem.hxx> 38 #include <svtools/colorcfg.hxx> 39 #include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS 40 #include <svx/fmview.hxx> 41 #include <editeng/frmdiritem.hxx> 42 #include <editeng/lrspitem.hxx> 43 #include <editeng/paperinf.hxx> 44 #include <editeng/pbinitem.hxx> 45 #include <editeng/shaditem.hxx> 46 #include <editeng/sizeitem.hxx> 47 #include <svx/svdpagv.hxx> 48 #include <editeng/ulspitem.hxx> 49 #include <sfx2/app.hxx> 50 #include <sfx2/printer.hxx> 51 #include <tools/multisel.hxx> 52 #include <sfx2/docfile.hxx> 53 #include <tools/urlobj.hxx> 54 #include <svx/xoutbmp.hxx> 55 56 #include "editutil.hxx" 57 #include "docsh.hxx" 58 #include "output.hxx" 59 #include "viewdata.hxx" 60 #include "viewopti.hxx" 61 #include "stlpool.hxx" 62 #include "pagepar.hxx" 63 #include "attrib.hxx" 64 #include "patattr.hxx" 65 #include "docpool.hxx" 66 #include "dociter.hxx" 67 #include "cell.hxx" 68 #include "drawutil.hxx" 69 #include "globstr.hrc" 70 #include "scresid.hxx" 71 #include "sc.hrc" 72 #include "pagedata.hxx" 73 #include "printopt.hxx" 74 #include "prevloc.hxx" 75 #include "scmod.hxx" 76 #include "drwlayer.hxx" 77 #include "fillinfo.hxx" 78 #include "postit.hxx" 79 80 #include <vcl/lineinfo.hxx> 81 #include <tools/pstm.hxx> 82 83 #include <boost/scoped_ptr.hpp> 84 85 #define ZOOM_MIN 10 86 87 #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue() 88 #define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue() 89 #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) ) 90 91 //------------------------------------------------------------------------ 92 93 ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r) 94 { 95 nStartRow = r.nStartRow; 96 nEndRow = r.nEndRow; 97 nPagesX = r.nPagesX; 98 if (r.pHidden && nPagesX) 99 { 100 pHidden = new sal_Bool[nPagesX]; 101 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) ); 102 } 103 else 104 pHidden = NULL; 105 } 106 107 const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r) 108 { 109 delete[] pHidden; 110 111 nStartRow = r.nStartRow; 112 nEndRow = r.nEndRow; 113 nPagesX = r.nPagesX; 114 if (r.pHidden && nPagesX) 115 { 116 pHidden = new sal_Bool[nPagesX]; 117 memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) ); 118 } 119 else 120 pHidden = NULL; 121 122 return *this; 123 } 124 125 void ScPageRowEntry::SetPagesX(size_t nNew) 126 { 127 if (pHidden) 128 { 129 DBG_ERROR("SetPagesX nicht nach SetHidden"); 130 delete[] pHidden; 131 pHidden = NULL; 132 } 133 nPagesX = nNew; 134 } 135 136 void ScPageRowEntry::SetHidden(size_t nX) 137 { 138 if ( nX < nPagesX ) 139 { 140 if ( nX+1 == nPagesX ) // letzte Seite? 141 --nPagesX; 142 else 143 { 144 if (!pHidden) 145 { 146 pHidden = new sal_Bool[nPagesX]; 147 memset( pHidden, sal_False, nPagesX * sizeof(sal_Bool) ); 148 } 149 pHidden[nX] = sal_True; 150 } 151 } 152 } 153 154 sal_Bool ScPageRowEntry::IsHidden(size_t nX) const 155 { 156 return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline? 157 } 158 159 size_t ScPageRowEntry::CountVisible() const 160 { 161 if ( pHidden ) 162 { 163 size_t nVis = 0; 164 for (size_t i=0; i<nPagesX; i++) 165 if (!pHidden[i]) 166 ++nVis; 167 return nVis; 168 } 169 else 170 return nPagesX; 171 } 172 173 //------------------------------------------------------------------------ 174 175 long lcl_LineTotal(const SvxBorderLine* pLine) 176 { 177 return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0; 178 } 179 180 void ScPrintFunc::Construct( const ScPrintOptions* pOptions ) 181 { 182 pDocShell->UpdatePendingRowHeights( nPrintTab ); 183 pDoc = pDocShell->GetDocument(); 184 185 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen 186 if (pDocPrinter) 187 aOldPrinterMode = pDocPrinter->GetMapMode(); 188 189 // einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!), 190 // weil die EditEngine sonst unterschiedliche Texthoehen liefert 191 pDev->SetMapMode(MAP_PIXEL); 192 193 pPageEndX = NULL; 194 pPageEndY = NULL; 195 pPageRows = NULL; 196 pBorderItem = NULL; 197 pBackgroundItem = NULL; 198 pShadowItem = NULL; 199 200 pEditEngine = NULL; 201 pEditDefaults = NULL; 202 203 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); 204 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( 205 pDoc->GetPageStyle( nPrintTab ), 206 SFX_STYLE_FAMILY_PAGE ); 207 if (pStyleSheet) 208 pParamSet = &pStyleSheet->GetItemSet(); 209 else 210 { 211 DBG_ERROR("Seitenvorlage nicht gefunden" ); 212 pParamSet = NULL; 213 } 214 215 if (!bState) 216 nZoom = 100; 217 nManualZoom = 100; 218 bClearWin = sal_False; 219 bUseStyleColor = sal_False; 220 bIsRender = sal_False; 221 222 InitParam(pOptions); 223 224 pPageData = NULL; // wird nur zur Initialisierung gebraucht 225 } 226 227 ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab, 228 long nPage, long nDocP, const ScRange* pArea, 229 const ScPrintOptions* pOptions, 230 ScPageBreakData* pData ) 231 : pDocShell ( pShell ), 232 pPrinter ( pNewPrinter ), 233 pDrawView ( NULL ), 234 nPrintTab ( nTab ), 235 nPageStart ( nPage ), 236 nDocPages ( nDocP ), 237 pUserArea ( pArea ), 238 bState ( sal_False ), 239 bSourceRangeValid ( sal_False ), 240 bPrintCurrentTable ( sal_False ), 241 bMultiArea ( sal_False ), 242 nTabPages ( 0 ), 243 nTotalPages ( 0 ), 244 pPageData ( pData ) 245 { 246 pDev = pPrinter; 247 aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM ); 248 Construct( pOptions ); 249 } 250 251 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab, 252 long nPage, long nDocP, const ScRange* pArea, 253 const ScPrintOptions* pOptions ) 254 : pDocShell ( pShell ), 255 pPrinter ( NULL ), 256 pDrawView ( NULL ), 257 nPrintTab ( nTab ), 258 nPageStart ( nPage ), 259 nDocPages ( nDocP ), 260 pUserArea ( pArea ), 261 bState ( sal_False ), 262 bSourceRangeValid ( sal_False ), 263 bPrintCurrentTable ( sal_False ), 264 bMultiArea ( sal_False ), 265 nTabPages ( 0 ), 266 nTotalPages ( 0 ), 267 pPageData ( NULL ) 268 { 269 pDev = pOutDev; 270 Construct( pOptions ); 271 } 272 273 ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, 274 const ScPrintState& rState, const ScPrintOptions* pOptions ) 275 : pDocShell ( pShell ), 276 pPrinter ( NULL ), 277 pDrawView ( NULL ), 278 pUserArea ( NULL ), 279 bSourceRangeValid ( sal_False ), 280 bPrintCurrentTable ( sal_False ), 281 bMultiArea ( sal_False ), 282 pPageData ( NULL ) 283 { 284 pDev = pOutDev; 285 286 nPrintTab = rState.nPrintTab; 287 nStartCol = rState.nStartCol; 288 nStartRow = rState.nStartRow; 289 nEndCol = rState.nEndCol; 290 nEndRow = rState.nEndRow; 291 nZoom = rState.nZoom; 292 nPagesX = rState.nPagesX; 293 nPagesY = rState.nPagesY; 294 nTabPages = rState.nTabPages; 295 nTotalPages = rState.nTotalPages; 296 nPageStart = rState.nPageStart; 297 nDocPages = rState.nDocPages; 298 bState = sal_True; 299 300 Construct( pOptions ); 301 } 302 303 void ScPrintFunc::GetPrintState( ScPrintState& rState ) 304 { 305 rState.nPrintTab = nPrintTab; 306 rState.nStartCol = nStartCol; 307 rState.nStartRow = nStartRow; 308 rState.nEndCol = nEndCol; 309 rState.nEndRow = nEndRow; 310 rState.nZoom = nZoom; 311 rState.nPagesX = nPagesX; 312 rState.nPagesY = nPagesY; 313 rState.nTabPages = nTabPages; 314 rState.nTotalPages = nTotalPages; 315 rState.nPageStart = nPageStart; 316 rState.nDocPages = nDocPages; 317 } 318 319 sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const 320 { 321 rRange = aLastSourceRange; 322 return bSourceRangeValid; 323 } 324 325 void ScPrintFunc::FillPageData() 326 { 327 if (pPageData) 328 { 329 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() ); 330 ScPrintRangeData& rData = pPageData->GetData(nCount); // hochzaehlen 331 332 rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab, 333 nEndCol, nEndRow, nPrintTab ) ); 334 rData.SetPagesX( nPagesX, pPageEndX ); 335 rData.SetPagesY( nTotalY, pPageEndY ); 336 337 // Einstellungen 338 rData.SetTopDown( aTableParam.bTopDown ); 339 rData.SetAutomatic( !aAreaParam.bPrintArea ); 340 } 341 } 342 343 ScPrintFunc::~ScPrintFunc() 344 { 345 ScAddress* pTripel = (ScAddress*) aNotePosList.First(); 346 while (pTripel) 347 { 348 delete pTripel; 349 pTripel = (ScAddress*) aNotePosList.Next(); 350 } 351 aNotePosList.Clear(); 352 353 delete[] pPageEndX; 354 delete[] pPageEndY; 355 delete[] pPageRows; 356 delete pEditDefaults; 357 delete pEditEngine; 358 359 // Druckereinstellungen werden jetzt von aussen wiederhergestellt 360 361 // #64294# Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen 362 SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen 363 if (pDocPrinter) 364 pDocPrinter->SetMapMode(aOldPrinterMode); 365 } 366 367 void ScPrintFunc::SetDrawView( FmFormView* pNew ) 368 { 369 pDrawView = pNew; 370 } 371 372 void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 ) 373 { 374 for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++) 375 { 376 RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY]; 377 for (SCCOL nX=nX1; nX<=nX2; nX++) 378 { 379 const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1]; 380 if (!rCellInfo.bEmptyCellText) 381 if (((const ScProtectionAttr&)rCellInfo.pPatternAttr-> 382 GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint()) 383 { 384 pThisRowInfo->pCellInfo[nX+1].pCell = NULL; 385 pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = sal_True; 386 } 387 } 388 } 389 } 390 391 // 392 // Ausgabe auf Device (static) 393 // 394 // wird benutzt fuer: 395 // - Clipboard/Bitmap 396 // - Ole-Object (DocShell::Draw) 397 // - Vorschau bei Vorlagen 398 399 void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */, 400 const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile ) 401 { 402 //! nPrintFactor auswerten !!! 403 404 SCTAB nTab = 0; 405 if (pViewData) 406 nTab = pViewData->GetTabNo(); 407 408 sal_Bool bDoGrid, bNullVal, bFormula; 409 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); 410 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE ); 411 if (pStyleSheet) 412 { 413 SfxItemSet& rSet = pStyleSheet->GetItemSet(); 414 bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue(); 415 bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue(); 416 bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue(); 417 } 418 else 419 { 420 const ScViewOptions& rOpt = pDoc->GetViewOptions(); 421 bDoGrid = rOpt.GetOption(VOPT_GRID); 422 bNullVal = rOpt.GetOption(VOPT_NULLVALS); 423 bFormula = rOpt.GetOption(VOPT_FORMULAS); 424 } 425 426 MapMode aMode = pDev->GetMapMode(); 427 428 Rectangle aRect = rBound; 429 430 if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top()) 431 aRect = Rectangle( Point(), pDev->GetOutputSize() ); 432 433 SCCOL nX1 = 0; 434 SCROW nY1 = 0; 435 SCCOL nX2 = OLE_STD_CELLS_X - 1; 436 SCROW nY2 = OLE_STD_CELLS_Y - 1; 437 if (bMetaFile) 438 { 439 ScRange aRange = pDoc->GetRange( nTab, rBound ); 440 nX1 = aRange.aStart.Col(); 441 nY1 = aRange.aStart.Row(); 442 nX2 = aRange.aEnd.Col(); 443 nY2 = aRange.aEnd.Row(); 444 } 445 else if (pViewData) 446 { 447 ScSplitPos eWhich = pViewData->GetActivePart(); 448 ScHSplitPos eHWhich = WhichH(eWhich); 449 ScVSplitPos eVWhich = WhichV(eWhich); 450 nX1 = pViewData->GetPosX(eHWhich); 451 nY1 = pViewData->GetPosY(eVWhich); 452 nX2 = nX1 + pViewData->VisibleCellsX(eHWhich); 453 if (nX2>nX1) --nX2; 454 nY2 = nY1 + pViewData->VisibleCellsY(eVWhich); 455 if (nY2>nY1) --nY2; 456 } 457 458 if (nX1 > MAXCOL) nX1 = MAXCOL; 459 if (nX2 > MAXCOL) nX2 = MAXCOL; 460 if (nY1 > MAXROW) nY1 = MAXROW; 461 if (nY2 > MAXROW) nY2 = MAXROW; 462 463 long nDevSizeX = aRect.Right()-aRect.Left()+1; 464 long nDevSizeY = aRect.Bottom()-aRect.Top()+1; 465 466 Rectangle aLines; 467 ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab ); 468 // sal_Bool bAddLines = pDoc->HasLines( aRange, aLines ); 469 470 long nTwipsSizeX = 0; 471 for (SCCOL i=nX1; i<=nX2; i++) 472 nTwipsSizeX += pDoc->GetColWidth( i, nTab ); 473 long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab ); 474 475 // wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt) 476 // (HasLines initalisiert aLines auf 0,0,0,0) 477 nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L ); 478 nTwipsSizeY += aLines.Top() + Max( aLines.Bottom(), 20L ); 479 480 double nScaleX = (double) nDevSizeX / nTwipsSizeX; 481 double nScaleY = (double) nDevSizeY / nTwipsSizeY; 482 483 //! Flag bei FillInfo uebergeben !!!!! 484 ScRange aERange; 485 sal_Bool bEmbed = pDoc->IsEmbedded(); 486 if (bEmbed) 487 { 488 pDoc->GetEmbedded(aERange); 489 pDoc->ResetEmbedded(); 490 } 491 492 // Daten zusammenstellen 493 494 ScTableInfo aTabInfo; 495 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, 496 nScaleX, nScaleY, sal_False, bFormula ); 497 lcl_HidePrint( aTabInfo, nX1, nX2 ); 498 499 if (bEmbed) 500 pDoc->SetEmbedded(aERange); 501 502 /* if (!bMetaFile) 503 pDev->SetMapMode(MAP_PIXEL); 504 */ 505 long nScrX = aRect.Left(); 506 long nScrY = aRect.Top(); 507 508 // Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen 509 // (werden sonst abgeschnitten) 510 long nAddX = (long)( aLines.Left() * nScaleX ); 511 nScrX += ( nAddX ? nAddX : 1 ); 512 long nAddY = (long)( aLines.Top() * nScaleY ); 513 nScrY += ( nAddY ? nAddY : 1 ); 514 515 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab, 516 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY ); 517 aOutputData.SetMetaFileMode(bMetaFile); 518 aOutputData.SetShowNullValues(bNullVal); 519 aOutputData.SetShowFormulas(bFormula); 520 521 // #114135# 522 ScDrawLayer* pModel = pDoc->GetDrawLayer(); 523 FmFormView* pDrawView = NULL; 524 525 if( pModel ) 526 { 527 pDrawView = new FmFormView( pModel, pDev ); 528 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab)); 529 pDrawView->SetPrintPreview( sal_True ); 530 aOutputData.SetDrawView( pDrawView ); 531 } 532 533 //! SetUseStyleColor ?? 534 535 if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV ) 536 aOutputData.SetSnapPixel(); 537 538 Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM ); 539 long nLogStX = aLogStart.X(); 540 long nLogStY = aLogStart.Y(); 541 542 //! nZoom fuer GetFont in OutputData ??? 543 544 if (!bMetaFile && pViewData) 545 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart())); 546 547 // #i72502# 548 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY)); 549 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset); 550 551 if (!bMetaFile && pViewData) 552 pDev->SetMapMode(aMode); 553 554 aOutputData.DrawBackground(); 555 556 #ifdef OS2 557 if (bMetaFile && !bDoGrid) 558 { 559 // unter OS2 fuer Metafiles gesamte Flaeche benutzen, 560 // weil sonst die Groesse nicht erkannt wird 561 pDev->SetLineColor(); 562 pDev->SetFillColor(); 563 pDev->DrawRect( Rectangle( nScrX,nScrY, 564 nScrX+aOutputData.GetScrW(), nScrY+aOutputData.GetScrH() ) ); 565 } 566 #endif 567 568 aOutputData.DrawShadow(); 569 aOutputData.DrawFrame(); 570 aOutputData.DrawStrings(); 571 572 if (!bMetaFile && pViewData) 573 pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart())); 574 575 aOutputData.DrawEdit(!bMetaFile); 576 577 if (bDoGrid) 578 { 579 if (!bMetaFile && pViewData) 580 pDev->SetMapMode(aMode); 581 582 aOutputData.DrawGrid( sal_True, sal_False ); // keine Seitenumbrueche 583 584 pDev->SetLineColor( COL_BLACK ); 585 586 Size aOne = pDev->PixelToLogic( Size(1,1) ); 587 if (bMetaFile) 588 aOne = Size(1,1); // compatible with DrawGrid 589 long nRight = nScrX + aOutputData.GetScrW() - aOne.Width(); 590 long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height(); 591 592 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 593 594 // extra line at the left edge for left-to-right, right for right-to-left 595 if ( bLayoutRTL ) 596 pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) ); 597 else 598 pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) ); 599 // extra line at the top in both cases 600 pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) ); 601 } 602 603 // #i72502# 604 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset); 605 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset); 606 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768# 607 608 // #114135# 609 delete pDrawView; 610 } 611 612 // 613 // Drucken 614 // 615 616 void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet ) 617 { 618 // nDistance muss vorher unterschiedlich initalisiert sein 619 620 if ( pHFSet == NULL ) 621 { 622 rParam.bEnable = sal_False; 623 rParam.pBorder = NULL; 624 rParam.pBack = NULL; 625 rParam.pShadow = NULL; 626 } 627 else 628 { 629 rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue(); 630 rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue(); 631 rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue(); 632 rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height(); 633 const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE); 634 long nTmp; 635 nTmp = pHFLR->GetLeft(); 636 rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp); 637 nTmp = pHFLR->GetRight(); 638 rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp); 639 rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER); 640 rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND); 641 rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);; 642 643 // jetzt doch wieder schon im Dialog: 644 // rParam.nHeight += rParam.nDistance; // nicht mehr im Dialog ??? 645 646 if (rParam.pBorder) 647 rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) + 648 lcl_LineTotal( rParam.pBorder->GetBottom() ); 649 650 rParam.nManHeight = rParam.nHeight; 651 } 652 653 if (!rParam.bEnable) 654 rParam.nHeight = 0; 655 } 656 657 // bNew = TRUE: benutzten Bereich aus dem Dokument suchen 658 // bNew = FALSE: nur ganze Zeilen/Spalten begrenzen 659 660 sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew ) 661 { 662 SCCOL nOldEndCol = nEndCol; // nur wichtig bei !bNew 663 SCROW nOldEndRow = nEndRow; 664 sal_Bool bChangeCol = sal_True; // bei bNew werden beide angepasst 665 sal_Bool bChangeRow = sal_True; 666 667 sal_Bool bNotes = aTableParam.bNotes; 668 if ( bNew ) 669 { 670 nStartCol = 0; 671 nStartRow = 0; 672 if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes )) 673 return sal_False; // nix 674 } 675 else 676 { 677 sal_Bool bFound = sal_True; 678 bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL ); 679 bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW ); 680 sal_Bool bForcedChangeRow = sal_False; 681 682 // #i53558# Crop entire column of old row limit to real print area with 683 // some fuzzyness. 684 if (!bChangeRow && nStartRow == 0) 685 { 686 SCROW nPAEndRow; 687 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes ); 688 // Say we don't want to print more than ~1000 empty rows, which are 689 // about 14 pages intentionally left blank.. 690 const SCROW nFuzzy = 23*42; 691 if (nPAEndRow + nFuzzy < nEndRow) 692 { 693 bForcedChangeRow = sal_True; 694 nEndRow = nPAEndRow; 695 } 696 else 697 bFound = sal_True; // user seems to _want_ to print some empty rows 698 } 699 // TODO: in case we extend the number of columns we may have to do the 700 // same for horizontal cropping. 701 702 if ( bChangeCol && bChangeRow ) 703 bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ); 704 else if ( bChangeCol ) 705 bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes ); 706 else if ( bChangeRow ) 707 bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes ); 708 709 if (!bFound) 710 return sal_False; // leer 711 712 if (bForcedChangeRow) 713 bChangeRow = sal_True; 714 } 715 716 pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab, 717 sal_False, sal_True ); // kein Refresh, incl. Attrs 718 719 if ( bChangeCol ) 720 { 721 OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen 722 pRefDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize 723 724 pDoc->ExtendPrintArea( pRefDev, 725 nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow ); 726 // nEndCol wird veraendert 727 } 728 729 if ( nEndCol < MAXCOL && pDoc->HasAttrib( 730 nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) ) 731 ++nEndCol; 732 if ( nEndRow < MAXROW && pDoc->HasAttrib( 733 nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) ) 734 ++nEndRow; 735 736 if (!bChangeCol) nEndCol = nOldEndCol; 737 if (!bChangeRow) nEndRow = nOldEndRow; 738 739 return sal_True; 740 } 741 742 long ScPrintFunc::TextHeight( const EditTextObject* pObject ) 743 { 744 if (!pObject) 745 return 0; 746 747 // pEditEngine->SetPageNo( nTotalPages ); 748 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False ); 749 750 return (long) pEditEngine->GetTextHeight(); 751 } 752 753 // nZoom muss gesetzt sein !!! 754 // und der entsprechende Twip-MapMode eingestellt 755 756 void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam ) 757 { 758 DBG_ASSERT( aPageSize.Width(), "UpdateHFHeight ohne aPageSize"); 759 760 if (rParam.bEnable && rParam.bDynamic) 761 { 762 // nHeight aus Inhalten berechnen 763 764 MakeEditEngine(); 765 long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin - 766 rParam.nLeft - rParam.nRight ) * 100 / nZoom; 767 if (rParam.pBorder) 768 nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) + 769 rParam.pBorder->GetDistance(BOX_LINE_RIGHT) + 770 lcl_LineTotal(rParam.pBorder->GetLeft()) + 771 lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom; 772 773 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) 774 nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) + 775 rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom; 776 777 pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) ); 778 779 long nMaxHeight = 0; 780 if ( rParam.pLeft ) 781 { 782 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) ); 783 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) ); 784 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) ); 785 } 786 if ( rParam.pRight ) 787 { 788 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) ); 789 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) ); 790 nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) ); 791 } 792 793 rParam.nHeight = nMaxHeight + rParam.nDistance; 794 if (rParam.pBorder) 795 rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) + 796 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) + 797 lcl_LineTotal( rParam.pBorder->GetTop() ) + 798 lcl_LineTotal( rParam.pBorder->GetBottom() ); 799 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) 800 rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) + 801 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); 802 803 if (rParam.nHeight < rParam.nManHeight) 804 rParam.nHeight = rParam.nManHeight; // eingestelltes Minimum 805 } 806 } 807 808 void ScPrintFunc::InitParam( const ScPrintOptions* pOptions ) 809 { 810 if (!pParamSet) 811 return; 812 813 // TabPage "Seite" 814 const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE ); 815 long nTmp; 816 nTmp = pLRItem->GetLeft(); 817 nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp); 818 nTmp = pLRItem->GetRight(); 819 nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp); 820 const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE ); 821 nTopMargin = pULItem->GetUpper(); 822 nBottomMargin = pULItem->GetLower(); 823 824 const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE ); 825 nPageUsage = pPageItem->GetPageUsage(); 826 bLandscape = pPageItem->IsLandscape(); 827 aFieldData.eNumType = pPageItem->GetNumType(); 828 829 bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue(); 830 bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue(); 831 832 aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize(); 833 if ( !aPageSize.Width() || !aPageSize.Height() ) 834 { 835 DBG_ERROR("PageSize Null ?!?!?"); 836 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); 837 } 838 839 pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER); 840 pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND); 841 pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW); 842 843 // TabPage "Kopfzeile" 844 845 aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Inhalt 846 aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT); 847 848 const SvxSetItem* pHeaderSetItem; 849 const SfxItemSet* pHeaderSet = NULL; 850 if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, sal_False, 851 (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET ) 852 { 853 pHeaderSet = &pHeaderSetItem->GetItemSet(); 854 // Kopfzeile hat unteren Abstand 855 aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower(); 856 } 857 lcl_FillHFParam( aHdr, pHeaderSet ); 858 859 // TabPage "Fusszeile" 860 861 aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Inhalt 862 aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT); 863 864 const SvxSetItem* pFooterSetItem; 865 const SfxItemSet* pFooterSet = NULL; 866 if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, sal_False, 867 (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET ) 868 { 869 pFooterSet = &pFooterSetItem->GetItemSet(); 870 // Fusszeile hat oberen Abstand 871 aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper(); 872 } 873 lcl_FillHFParam( aFtr, pFooterSet ); 874 875 //------------------------------------------------------ 876 // Table-/Area-Params aus einzelnen Items zusammenbauen: 877 //------------------------------------------------------ 878 // TabPage "Tabelle" 879 880 const SfxUInt16Item* pScaleItem = NULL; 881 const ScPageScaleToItem* pScaleToItem = NULL; 882 const SfxUInt16Item* pScaleToPagesItem = NULL; 883 SfxItemState eState; 884 885 eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, sal_False, 886 (const SfxPoolItem**)&pScaleItem ); 887 if ( SFX_ITEM_DEFAULT == eState ) 888 pScaleItem = (const SfxUInt16Item*) 889 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE ); 890 891 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, sal_False, 892 (const SfxPoolItem**)&pScaleToItem ); 893 if ( SFX_ITEM_DEFAULT == eState ) 894 pScaleToItem = (const ScPageScaleToItem*) 895 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO ); 896 897 eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, sal_False, 898 (const SfxPoolItem**)&pScaleToPagesItem ); 899 if ( SFX_ITEM_DEFAULT == eState ) 900 pScaleToPagesItem = (const SfxUInt16Item*) 901 &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES ); 902 903 DBG_ASSERT( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" ); 904 905 aTableParam.bCellContent = sal_True; 906 aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES); 907 aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID); 908 aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS); 909 aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS); 910 aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS); 911 aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS); 912 aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS); 913 aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS); 914 aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN); 915 aTableParam.bLeftRight = !aTableParam.bLeftRight; 916 aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO); 917 if (!aTableParam.nFirstPageNo) 918 aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // von vorheriger Tabelle 919 920 if ( pScaleItem && pScaleToItem && pScaleToPagesItem ) 921 { 922 sal_uInt16 nScaleAll = pScaleItem->GetValue(); 923 sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue(); 924 925 aTableParam.bScaleNone = (nScaleAll == 100); 926 aTableParam.bScaleAll = (nScaleAll > 0 ); 927 aTableParam.bScaleTo = pScaleToItem->IsValid(); 928 aTableParam.bScalePageNum = (nScaleToPages > 0 ); 929 aTableParam.nScaleAll = nScaleAll; 930 aTableParam.nScaleWidth = pScaleToItem->GetWidth(); 931 aTableParam.nScaleHeight = pScaleToItem->GetHeight(); 932 aTableParam.nScalePageNum = nScaleToPages; 933 } 934 else 935 { 936 aTableParam.bScaleNone = sal_True; 937 aTableParam.bScaleAll = sal_False; 938 aTableParam.bScaleTo = sal_False; 939 aTableParam.bScalePageNum = sal_False; 940 aTableParam.nScaleAll = 0; 941 aTableParam.nScaleWidth = 0; 942 aTableParam.nScaleHeight = 0; 943 aTableParam.nScalePageNum = 0; 944 } 945 946 // skip empty pages only if options with that flag are passed 947 aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty(); 948 if ( pPageData ) 949 aTableParam.bSkipEmpty = sal_False; 950 // Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau 951 // nur die Umbrueche, leere Seiten werden nicht speziell behandelt 952 953 //------------------------------------------------------ 954 // TabPage "Bereiche": 955 //------------------------------------------------------ 956 957 //! alle PrintAreas der Tabelle durchgehen !!! 958 const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 ); 959 const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab ); 960 const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab ); 961 962 // ATTR_PAGE_PRINTTABLES wird ignoriert 963 964 if ( pUserArea ) // UserArea (Selektion) hat Vorrang 965 { 966 bPrintCurrentTable = 967 aAreaParam.bPrintArea = sal_True; // Selektion 968 aAreaParam.aPrintArea = *pUserArea; 969 970 // Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer 971 aAreaParam.aPrintArea.aStart.SetTab(nPrintTab); 972 aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab); 973 974 // lcl_LimitRange( aAreaParam.aPrintArea, nPrintTab ); // ganze Zeilen/Spalten... 975 } 976 else if ( pDoc->HasPrintRange() ) 977 { 978 if ( pPrintArea ) // mindestens eine gesetzt ? 979 { 980 bPrintCurrentTable = 981 aAreaParam.bPrintArea = sal_True; 982 aAreaParam.aPrintArea = *pPrintArea; 983 984 bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 ); 985 } 986 else 987 { 988 // do not print hidden sheets with "Print entire sheet" flag 989 bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab ); 990 aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted 991 } 992 } 993 else 994 { 995 // #74834# don't print hidden tables if there's no print range defined there 996 if ( pDoc->IsVisible( nPrintTab ) ) 997 { 998 aAreaParam.bPrintArea = sal_False; 999 bPrintCurrentTable = sal_True; 1000 } 1001 else 1002 { 1003 aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted 1004 bPrintCurrentTable = sal_False; 1005 } 1006 } 1007 1008 if ( pRepeatCol ) 1009 { 1010 aAreaParam.bRepeatCol = sal_True; 1011 aAreaParam.aRepeatCol = *pRepeatCol; 1012 nRepeatStartCol = pRepeatCol->aStart.Col(); 1013 nRepeatEndCol = pRepeatCol->aEnd .Col(); 1014 } 1015 else 1016 { 1017 aAreaParam.bRepeatCol = sal_False; 1018 nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE; 1019 } 1020 1021 if ( pRepeatRow ) 1022 { 1023 aAreaParam.bRepeatRow = sal_True; 1024 aAreaParam.aRepeatRow = *pRepeatRow; 1025 nRepeatStartRow = pRepeatRow->aStart.Row(); 1026 nRepeatEndRow = pRepeatRow->aEnd .Row(); 1027 } 1028 else 1029 { 1030 aAreaParam.bRepeatRow = sal_False; 1031 nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE; 1032 } 1033 1034 // 1035 // Seiten aufteilen 1036 // 1037 1038 if (!bState) 1039 { 1040 nTabPages = CountPages(); // berechnet auch Zoom 1041 nTotalPages = nTabPages; 1042 nTotalPages += CountNotePages(); 1043 } 1044 else 1045 { 1046 CalcPages(); // nur Umbrueche suchen 1047 CountNotePages(); // Notizen zaehlen, auch wenn Seitenzahl schon bekannt 1048 } 1049 1050 if (nDocPages) 1051 aFieldData.nTotalPages = nDocPages; 1052 else 1053 aFieldData.nTotalPages = nTotalPages; 1054 1055 SetDateTime( Date(), Time() ); 1056 1057 aFieldData.aTitle = pDocShell->GetTitle(); 1058 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject(); 1059 aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); 1060 if ( aFieldData.aLongDocName.Len() ) 1061 aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS ); 1062 else 1063 aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle; 1064 1065 // Druckereinstellungen (Orientation, Paper) jetzt erst bei DoPrint 1066 } 1067 1068 Size ScPrintFunc::GetDataSize() const 1069 { 1070 Size aSize = aPageSize; 1071 aSize.Width() -= nLeftMargin + nRightMargin; 1072 aSize.Height() -= nTopMargin + nBottomMargin; 1073 aSize.Height() -= aHdr.nHeight + aFtr.nHeight; 1074 return aSize; 1075 } 1076 1077 void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr ) 1078 { 1079 rPhysSize = aPageSize; 1080 rPhysSize.Width() -= nLeftMargin + nRightMargin; 1081 rPhysSize.Height() -= nTopMargin + nBottomMargin; 1082 1083 rDocHdr = aHdr.nHeight; 1084 rDocFtr = aFtr.nHeight; 1085 } 1086 1087 void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime ) 1088 { 1089 aFieldData.aDate = rDate; 1090 aFieldData.aTime = rTime; 1091 } 1092 1093 void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut, 1094 const Rectangle &rGrf, const Rectangle &rOut ) 1095 { 1096 const FASTBOOL bNotInside = !rOut.IsInside( rGrf ); 1097 if ( bNotInside ) 1098 { 1099 pOut->Push(); 1100 pOut->IntersectClipRegion( rOut ); 1101 } 1102 1103 ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() ); 1104 1105 if ( bNotInside ) 1106 pOut->Pop(); 1107 } 1108 1109 void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev, 1110 const Rectangle &rOrg, const Rectangle &rOut ) 1111 { 1112 Size aGrfSize(0,0); 1113 const Graphic *pGraphic = rBrush.GetGraphic(); 1114 SvxGraphicPosition ePos; 1115 if ( pGraphic && pGraphic->IsSupportedGraphic() ) 1116 { 1117 const MapMode aMapMM( MAP_100TH_MM ); 1118 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL ) 1119 aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM ); 1120 else 1121 aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(), 1122 pGraphic->GetPrefMapMode(), aMapMM ); 1123 ePos = rBrush.GetGraphicPos(); 1124 } 1125 else 1126 ePos = GPOS_NONE; 1127 1128 Point aPos; 1129 Size aDrawSize = aGrfSize; 1130 1131 FASTBOOL bDraw = sal_True; 1132 // FASTBOOL bRetouche = sal_True; 1133 switch ( ePos ) 1134 { 1135 case GPOS_LT: aPos = rOrg.TopLeft(); 1136 break; 1137 case GPOS_MT: aPos.Y() = rOrg.Top(); 1138 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; 1139 break; 1140 case GPOS_RT: aPos.Y() = rOrg.Top(); 1141 aPos.X() = rOrg.Right() - aGrfSize.Width(); 1142 break; 1143 1144 case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; 1145 aPos.X() = rOrg.Left(); 1146 break; 1147 case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; 1148 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; 1149 break; 1150 case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; 1151 aPos.X() = rOrg.Right() - aGrfSize.Width(); 1152 break; 1153 1154 case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); 1155 aPos.X() = rOrg.Left(); 1156 break; 1157 case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); 1158 aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; 1159 break; 1160 case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); 1161 aPos.X() = rOrg.Right() - aGrfSize.Width(); 1162 break; 1163 1164 case GPOS_AREA: 1165 aPos = rOrg.TopLeft(); 1166 aDrawSize = rOrg.GetSize(); 1167 // bRetouche = sal_False; 1168 break; 1169 case GPOS_TILED: 1170 { 1171 // #104004# use GraphicObject::DrawTiled instead of an own loop 1172 // (pixel rounding is handled correctly, and a very small bitmap 1173 // is duplicated into a bigger one for better performance) 1174 1175 GraphicObject aObject( *pGraphic ); 1176 1177 if( pOut->GetPDFWriter() && 1178 (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) ) 1179 { 1180 // #104004# For PDF export, every draw 1181 // operation for bitmaps takes a noticeable 1182 // amount of place (~50 characters). Thus, 1183 // optimize between tile bitmap size and 1184 // number of drawing operations here. 1185 // 1186 // A_out 1187 // n_chars = k1 * ---------- + k2 * A_bitmap 1188 // A_bitmap 1189 // 1190 // minimum n_chars is obtained for (derive for 1191 // A_bitmap, set to 0, take positive 1192 // solution): 1193 // k1 1194 // A_bitmap = Sqrt( ---- A_out ) 1195 // k2 1196 // 1197 // where k1 is the number of chars per draw 1198 // operation, and k2 is the number of chars 1199 // per bitmap pixel. This is approximately 50 1200 // and 7 for current PDF writer, respectively. 1201 // 1202 const double k1( 50 ); 1203 const double k2( 7 ); 1204 const Size aSize( rOrg.GetSize() ); 1205 const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() ); 1206 1207 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0), 1208 NULL, GRFMGR_DRAW_STANDARD, 1209 ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) ); 1210 } 1211 else 1212 { 1213 aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) ); 1214 } 1215 1216 bDraw = sal_False; 1217 // bRetouche = sal_False; 1218 } 1219 break; 1220 1221 case GPOS_NONE: 1222 bDraw = sal_False; 1223 break; 1224 1225 default: DBG_ASSERT( !pOut, "new Graphic position?" ); 1226 } 1227 Rectangle aGrf( aPos,aDrawSize ); 1228 if ( bDraw && aGrf.IsOver( rOut ) ) 1229 { 1230 lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut ); 1231 } 1232 } 1233 1234 // Rahmen wird nach innen gezeichnet 1235 1236 void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH, 1237 const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground, 1238 const SvxShadowItem* pShadow ) 1239 { 1240 //! direkte Ausgabe aus SvxBoxItem !!! 1241 1242 if (pBorderData) 1243 if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() && 1244 !pBorderData->GetRight() ) 1245 pBorderData = NULL; 1246 1247 if (!pBorderData && !pBackground && !pShadow) 1248 return; // nichts zu tun 1249 1250 long nLeft = 0; 1251 long nRight = 0; 1252 long nTop = 0; 1253 long nBottom = 0; 1254 1255 // aFrameRect - aussen um die Umrandung, ohne Schatten 1256 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE ) 1257 { 1258 nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX ); 1259 nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX ); 1260 nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY ); 1261 nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY ); 1262 } 1263 Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop), 1264 Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) ); 1265 1266 // Mitte der Umrandung, um Linien ueber OutputData zu zeichnen: 1267 if (pBorderData) 1268 { 1269 nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 ); 1270 nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 ); 1271 nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 ); 1272 nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 ); 1273 } 1274 long nEffHeight = nScrH - nTop - nBottom; 1275 long nEffWidth = nScrW - nLeft - nRight; 1276 if (nEffHeight<=0 || nEffWidth<=0) 1277 return; // leer 1278 1279 // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True) 1280 sal_Bool bCellContrast = bUseStyleColor && 1281 Application::GetSettings().GetStyleSettings().GetHighContrastMode(); 1282 1283 if ( pBackground && !bCellContrast ) 1284 { 1285 // Rectangle aBackRect( Point(nScrX+nLeft, nScrY+nTop), Size(nEffWidth,nEffHeight) ); 1286 if (pBackground->GetGraphicPos() != GPOS_NONE) 1287 { 1288 OutputDevice* pRefDev; 1289 if ( bIsRender ) 1290 pRefDev = pDev; // don't use printer for PDF 1291 else 1292 pRefDev = pDoc->GetPrinter(); // use printer also for preview 1293 1294 lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect ); 1295 } 1296 else 1297 { 1298 pDev->SetFillColor(pBackground->GetColor()); 1299 pDev->SetLineColor(); 1300 pDev->DrawRect(aFrameRect); 1301 } 1302 } 1303 1304 if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE ) 1305 { 1306 if ( bCellContrast ) 1307 pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 1308 else 1309 pDev->SetFillColor(pShadow->GetColor()); 1310 pDev->SetLineColor(); 1311 long nShadowX = (long) ( pShadow->GetWidth() * nScaleX ); 1312 long nShadowY = (long) ( pShadow->GetWidth() * nScaleY ); 1313 switch (pShadow->GetLocation()) 1314 { 1315 case SVX_SHADOW_TOPLEFT: 1316 pDev->DrawRect( Rectangle( 1317 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY, 1318 aFrameRect.Right()-nShadowX, aFrameRect.Top() ) ); 1319 pDev->DrawRect( Rectangle( 1320 aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY, 1321 aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) ); 1322 break; 1323 case SVX_SHADOW_TOPRIGHT: 1324 pDev->DrawRect( Rectangle( 1325 aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY, 1326 aFrameRect.Right()+nShadowX, aFrameRect.Top() ) ); 1327 pDev->DrawRect( Rectangle( 1328 aFrameRect.Right(), aFrameRect.Top()-nShadowY, 1329 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) ); 1330 break; 1331 case SVX_SHADOW_BOTTOMLEFT: 1332 pDev->DrawRect( Rectangle( 1333 aFrameRect.Left()-nShadowX, aFrameRect.Bottom(), 1334 aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) ); 1335 pDev->DrawRect( Rectangle( 1336 aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY, 1337 aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) ); 1338 break; 1339 case SVX_SHADOW_BOTTOMRIGHT: 1340 pDev->DrawRect( Rectangle( 1341 aFrameRect.Left()+nShadowX, aFrameRect.Bottom(), 1342 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) ); 1343 pDev->DrawRect( Rectangle( 1344 aFrameRect.Right(), aFrameRect.Top()+nShadowY, 1345 aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) ); 1346 break; 1347 default: 1348 { 1349 // added to avoid warnings 1350 } 1351 } 1352 } 1353 1354 if (pBorderData) 1355 { 1356 ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO ); 1357 pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True ); 1358 if (pBorderData) 1359 pBorderDoc->ApplyAttr( 0,0,0, *pBorderData ); 1360 1361 ScTableInfo aTabInfo; 1362 pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0, 1363 nScaleX, nScaleY, sal_False, sal_False ); 1364 DBG_ASSERT(aTabInfo.mnArrCount,"nArrCount == 0"); 1365 1366 aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight; 1367 aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth = 1368 aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth; 1369 1370 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0, 1371 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY ); 1372 aOutputData.SetUseStyleColor( bUseStyleColor ); 1373 1374 // pDev->SetMapMode(aTwipMode); 1375 1376 if (pBorderData) 1377 aOutputData.DrawFrame(); 1378 1379 delete pBorderDoc; 1380 } 1381 } 1382 1383 void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY ) 1384 { 1385 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); 1386 long nLayoutSign = bLayoutRTL ? -1 : 1; 1387 1388 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 1389 long nOneX = aOnePixel.Width(); 1390 long nOneY = aOnePixel.Height(); 1391 SCCOL nCol; 1392 1393 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); 1394 long nEndY = nScrY + nHeight - nOneY; 1395 1396 long nPosX = nScrX; 1397 if ( bLayoutRTL ) 1398 { 1399 for (nCol=nX1; nCol<=nX2; nCol++) 1400 nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX ); 1401 } 1402 else 1403 nPosX -= nOneX; 1404 long nPosY = nScrY - nOneY; 1405 String aText; 1406 1407 for (nCol=nX1; nCol<=nX2; nCol++) 1408 { 1409 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); 1410 if (nDocW) 1411 { 1412 long nWidth = (long) (nDocW * nScaleX); 1413 long nEndX = nPosX + nWidth * nLayoutSign; 1414 1415 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) ); 1416 1417 aText = ::ScColToAlpha( nCol); 1418 long nTextWidth = pDev->GetTextWidth(aText); 1419 long nTextHeight = pDev->GetTextHeight(); 1420 long nAddX = ( nWidth - nTextWidth ) / 2; 1421 long nAddY = ( nHeight - nTextHeight ) / 2; 1422 long nTextPosX = nPosX+nAddX; 1423 if ( bLayoutRTL ) 1424 nTextPosX -= nWidth; 1425 pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText ); 1426 1427 nPosX = nEndX; 1428 } 1429 } 1430 } 1431 1432 void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY ) 1433 { 1434 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 1435 long nOneX = aOnePixel.Width(); 1436 long nOneY = aOnePixel.Height(); 1437 1438 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); 1439 1440 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); 1441 long nEndX = nScrX + nWidth; 1442 long nPosX = nScrX; 1443 if ( !bLayoutRTL ) 1444 { 1445 nEndX -= nOneX; 1446 nPosX -= nOneX; 1447 } 1448 long nPosY = nScrY - nOneY; 1449 String aText; 1450 1451 for (SCROW nRow=nY1; nRow<=nY2; nRow++) 1452 { 1453 sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab ); 1454 if (nDocH) 1455 { 1456 long nHeight = (long) (nDocH * nScaleY); 1457 long nEndY = nPosY + nHeight; 1458 1459 pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) ); 1460 1461 aText = String::CreateFromInt32( nRow+1 ); 1462 long nTextWidth = pDev->GetTextWidth(aText); 1463 long nTextHeight = pDev->GetTextHeight(); 1464 long nAddX = ( nWidth - nTextWidth ) / 2; 1465 long nAddY = ( nHeight - nTextHeight ) / 2; 1466 pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText ); 1467 1468 nPosY = nEndY; 1469 } 1470 } 1471 } 1472 1473 void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY, 1474 sal_Bool bRepCol, ScPreviewLocationData& rLocationData ) 1475 { 1476 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 1477 long nOneX = aOnePixel.Width(); 1478 long nOneY = aOnePixel.Height(); 1479 1480 long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); 1481 long nEndY = nScrY + nHeight - nOneY; 1482 1483 long nPosX = nScrX - nOneX; 1484 for (SCCOL nCol=nX1; nCol<=nX2; nCol++) 1485 { 1486 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); 1487 if (nDocW) 1488 nPosX += (long) (nDocW * nScaleX); 1489 } 1490 Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY ); 1491 rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol ); 1492 } 1493 1494 void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY, 1495 sal_Bool bRepRow, ScPreviewLocationData& rLocationData ) 1496 { 1497 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 1498 long nOneX = aOnePixel.Width(); 1499 long nOneY = aOnePixel.Height(); 1500 1501 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); 1502 1503 long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); 1504 long nEndX = nScrX + nWidth; 1505 if ( !bLayoutRTL ) 1506 nEndX -= nOneX; 1507 1508 long nPosY = nScrY - nOneY; 1509 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); 1510 Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY ); 1511 rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow ); 1512 } 1513 1514 void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, 1515 long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow, 1516 ScPreviewLocationData& rLocationData ) 1517 { 1518 // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer) 1519 1520 Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode); 1521 long nLogStX = aLogPos.X(); 1522 long nLogStY = aLogPos.Y(); 1523 1524 SCCOL nCol; 1525 Point aTwipOffset; 1526 for (nCol=0; nCol<nX1; nCol++) 1527 aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab ); 1528 aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab ); 1529 1530 Point aMMOffset( aTwipOffset ); 1531 aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS); 1532 aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS); 1533 aMMOffset += Point( nLogStX, nLogStY ); 1534 MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() ); 1535 1536 // get pixel rectangle 1537 1538 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 1539 long nOneX = aOnePixel.Width(); 1540 long nOneY = aOnePixel.Height(); 1541 1542 long nPosX = nScrX - nOneX; 1543 for (nCol=nX1; nCol<=nX2; nCol++) 1544 { 1545 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); 1546 if (nDocW) 1547 nPosX += (long) (nDocW * nScaleX); 1548 } 1549 1550 long nPosY = nScrY - nOneY; 1551 nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); 1552 Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY ); 1553 rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ), 1554 bRepCol, bRepRow, aDrawMapMode ); 1555 } 1556 1557 void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, 1558 long nScrX, long nScrY, 1559 sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom ) 1560 { 1561 // #i47547# nothing to do if the end of the print area is before the end of 1562 // the repeat columns/rows (don't use negative size for ScOutputData) 1563 if ( nX2 < nX1 || nY2 < nY1 ) 1564 return; 1565 1566 //! Flag bei FillInfo uebergeben !!!!! 1567 ScRange aERange; 1568 sal_Bool bEmbed = pDoc->IsEmbedded(); 1569 if (bEmbed) 1570 { 1571 pDoc->GetEmbedded(aERange); 1572 pDoc->ResetEmbedded(); 1573 } 1574 1575 Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode); 1576 long nLogStX = aPos.X(); 1577 long nLogStY = aPos.Y(); 1578 1579 // Daten zusammenstellen 1580 1581 ScTableInfo aTabInfo; 1582 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab, 1583 nScaleX, nScaleY, sal_True, aTableParam.bFormulas ); 1584 lcl_HidePrint( aTabInfo, nX1, nX2 ); 1585 1586 if (bEmbed) 1587 pDoc->SetEmbedded(aERange); 1588 1589 ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab, 1590 nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY ); 1591 1592 // #114135# 1593 aOutputData.SetDrawView( pDrawView ); 1594 1595 // test if all paint parts are hidden, then a paint is not necessary at all 1596 const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY)); 1597 const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart() 1598 && pDrawView->getHideDraw() && pDrawView->getHideFormControl() ); 1599 1600 if(!bHideAllDrawingLayer) 1601 { 1602 pDev->SetMapMode(aLogicMode); 1603 // hier kein Clipping setzen (Mapmode wird verschoben) 1604 1605 // #i72502# 1606 aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset); 1607 } 1608 1609 pDev->SetMapMode(aOffsetMode); 1610 1611 aOutputData.SetShowFormulas( aTableParam.bFormulas ); 1612 aOutputData.SetShowNullValues( aTableParam.bNullVals ); 1613 aOutputData.SetUseStyleColor( bUseStyleColor ); 1614 1615 Color aGridColor( COL_BLACK ); 1616 if ( bUseStyleColor ) 1617 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 1618 aOutputData.SetGridColor( aGridColor ); 1619 1620 if ( !pPrinter ) 1621 { 1622 OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen 1623 Fraction aPrintFrac( nZoom, 100 ); // ohne nManualZoom 1624 // MapMode, wie er beim Drucken herauskommen wuerde: 1625 pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) ); 1626 1627 // when rendering (PDF), don't use printer as ref device, but printer's MapMode 1628 // has to be set anyway, as charts still use it (#106409#) 1629 if ( !bIsRender ) 1630 aOutputData.SetRefDevice( pRefDev ); 1631 } 1632 1633 // aOutputData.SetMetaFileMode(sal_True); 1634 if( aTableParam.bCellContent ) 1635 aOutputData.DrawBackground(); 1636 1637 pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ); 1638 pDev->SetClipRegion(); 1639 1640 // aOutputData.SetMetaFileMode(sal_False); 1641 if( aTableParam.bCellContent ) 1642 { 1643 aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom ); 1644 aOutputData.DrawFrame(); 1645 aOutputData.DrawStrings(); 1646 1647 // pDev->SetMapMode(aLogicMode); 1648 aOutputData.DrawEdit(sal_False); 1649 } 1650 1651 // pDev->SetMapMode(aOffsetMode); 1652 if (aTableParam.bGrid) 1653 aOutputData.DrawGrid( sal_True, sal_False ); // keine Seitenumbrueche 1654 1655 /*!!!!!!!!!!! Notizen in Tabelle markieren ?????????????????????????? 1656 1657 if (aTableParam.bNotes) 1658 { 1659 pDev->SetMapMode(aOffsetMode); 1660 aOutputData.PrintNoteMarks(aNotePosList); 1661 pDev->SetMapMode(aLogicMode); 1662 } 1663 */ 1664 1665 aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled 1666 1667 // pDev->SetMapMode(aDrawMode); 1668 1669 // test if all paint parts are hidden, then a paint is not necessary at all 1670 if(!bHideAllDrawingLayer) 1671 { 1672 // #i72502# 1673 aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset); 1674 } 1675 1676 // #i72502# 1677 aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset); 1678 aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768# 1679 } 1680 1681 sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Raender spiegeln ? 1682 { 1683 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f ); 1684 return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) ); 1685 } 1686 1687 sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // linke Fussnoten ? 1688 { 1689 SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f ); 1690 sal_Bool bLeft; 1691 if (eUsage == SVX_PAGE_LEFT) 1692 bLeft = sal_True; 1693 else if (eUsage == SVX_PAGE_RIGHT) 1694 bLeft = sal_False; 1695 else 1696 bLeft = (nPageNo & 1) != 0; 1697 return bLeft; 1698 } 1699 1700 void ScPrintFunc::MakeTableString() 1701 { 1702 pDoc->GetName( nPrintTab, aFieldData.aTabName ); 1703 } 1704 1705 void ScPrintFunc::MakeEditEngine() 1706 { 1707 if (!pEditEngine) 1708 { 1709 // can't use document's edit engine pool here, 1710 // because pool must have twips as default metric 1711 pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True ); 1712 1713 pEditEngine->EnableUndo(sal_False); 1714 pEditEngine->SetRefDevice( pDev ); 1715 pEditEngine->SetWordDelimiters( 1716 ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); 1717 pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS ); 1718 pDoc->ApplyAsianEditSettings( *pEditEngine ); 1719 pEditEngine->EnableAutoColor( bUseStyleColor ); 1720 1721 // Default-Set fuer Ausrichtung 1722 pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); 1723 1724 const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN); 1725 rPattern.FillEditItemSet( pEditDefaults ); 1726 // FillEditItemSet adjusts font height to 1/100th mm, 1727 // but for header/footer twips is needed, as in the PatternAttr: 1728 pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT ); 1729 pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK ); 1730 pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL ); 1731 // #69193# dont use font color, because background color is not used 1732 //! there's no way to set the background for note pages 1733 pEditDefaults->ClearItem( EE_CHAR_COLOR ); 1734 if (ScGlobal::IsSystemRTL()) 1735 pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); 1736 } 1737 1738 pEditEngine->SetData( aFieldData ); // Seitennummer etc. setzen 1739 } 1740 1741 // nStartY = logic 1742 void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY, 1743 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) 1744 { 1745 const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr; 1746 1747 pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips 1748 1749 sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared; 1750 const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight; 1751 1752 long nLineStartX = aPageRect.Left() + rParam.nLeft; 1753 long nLineEndX = aPageRect.Right() - rParam.nRight; 1754 long nLineWidth = nLineEndX - nLineStartX + 1; 1755 1756 // Edit-Engine 1757 1758 Point aStart( nLineStartX, nStartY ); 1759 Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance ); 1760 if ( rParam.pBorder ) 1761 { 1762 long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT); 1763 long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP); 1764 aStart.X() += nLeft; 1765 aStart.Y() += nTop; 1766 aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT); 1767 aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM); 1768 } 1769 1770 if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE ) 1771 { 1772 long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT); 1773 long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP); 1774 aStart.X() += nLeft; 1775 aStart.Y() += nTop; 1776 aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT); 1777 aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); 1778 } 1779 1780 aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo; 1781 MakeEditEngine(); 1782 1783 pEditEngine->SetPaperSize(aPaperSize); 1784 const EditTextObject* pObject; 1785 1786 // Rahmen / Hintergrund 1787 1788 Point aBorderStart( nLineStartX, nStartY ); 1789 Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance ); 1790 if ( rParam.bDynamic ) 1791 { 1792 // hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen 1793 // und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.) 1794 1795 long nMaxHeight = 0; 1796 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) ); 1797 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) ); 1798 nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) ); 1799 if (rParam.pBorder) 1800 nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) + 1801 lcl_LineTotal( rParam.pBorder->GetBottom() ) + 1802 rParam.pBorder->GetDistance(BOX_LINE_TOP) + 1803 rParam.pBorder->GetDistance(BOX_LINE_BOTTOM); 1804 if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) 1805 nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) + 1806 rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); 1807 1808 if (nMaxHeight < rParam.nManHeight-rParam.nDistance) 1809 nMaxHeight = rParam.nManHeight-rParam.nDistance; // eingestelltes Minimum 1810 1811 aBorderSize.Height() = nMaxHeight; 1812 } 1813 1814 if ( bDoPrint ) 1815 { 1816 double nOldScaleX = nScaleX; 1817 double nOldScaleY = nScaleY; 1818 nScaleX = nScaleY = 1.0; // direkt in Twips ausgeben 1819 DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(), 1820 rParam.pBorder, rParam.pBack, rParam.pShadow ); 1821 nScaleX = nOldScaleX; 1822 nScaleY = nOldScaleY; 1823 1824 // Clipping fuer Text 1825 1826 pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) ); 1827 1828 // links 1829 1830 pObject = pHFItem->GetLeftArea(); 1831 if (pObject) 1832 { 1833 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); 1834 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False ); 1835 Point aDraw = aStart; 1836 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); 1837 if (nDif > 0) 1838 aDraw.Y() += nDif / 2; 1839 pEditEngine->Draw( pDev, aDraw, 0 ); 1840 } 1841 1842 // Mitte 1843 1844 pObject = pHFItem->GetCenterArea(); 1845 if (pObject) 1846 { 1847 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) ); 1848 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False ); 1849 Point aDraw = aStart; 1850 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); 1851 if (nDif > 0) 1852 aDraw.Y() += nDif / 2; 1853 pEditEngine->Draw( pDev, aDraw, 0 ); 1854 } 1855 1856 // rechts 1857 1858 pObject = pHFItem->GetRightArea(); 1859 if (pObject) 1860 { 1861 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); 1862 pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False ); 1863 Point aDraw = aStart; 1864 long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); 1865 if (nDif > 0) 1866 aDraw.Y() += nDif / 2; 1867 pEditEngine->Draw( pDev, aDraw, 0 ); 1868 } 1869 1870 pDev->SetClipRegion(); 1871 } 1872 1873 if ( pLocationData ) 1874 { 1875 Rectangle aHeaderRect( aBorderStart, aBorderSize ); 1876 pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft ); 1877 } 1878 } 1879 1880 long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) 1881 { 1882 if (bDoPrint) 1883 pDev->SetMapMode(aTwipMode); 1884 1885 MakeEditEngine(); 1886 pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); 1887 pEditEngine->SetDefaults( *pEditDefaults ); 1888 1889 Font aMarkFont; 1890 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT; 1891 ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode ); 1892 //? aMarkFont.SetWeight( WEIGHT_BOLD ); 1893 pDev->SetFont( aMarkFont ); 1894 long nMarkLen = pDev->GetTextWidth( 1895 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:"))); 1896 // ohne Space, weil's eh selten so weit kommt 1897 1898 Size aDataSize = aPageRect.GetSize(); 1899 if ( nMarkLen > aDataSize.Width() / 2 ) // alles viel zu klein? 1900 nMarkLen = aDataSize.Width() / 2; // Seite bruederlich aufteilen 1901 aDataSize.Width() -= nMarkLen; 1902 1903 pEditEngine->SetPaperSize( aDataSize ); 1904 long nPosX = aPageRect.Left() + nMarkLen; 1905 long nPosY = aPageRect.Top(); 1906 1907 long nCount = 0; 1908 sal_Bool bOk; 1909 do 1910 { 1911 bOk = sal_False; 1912 ScAddress* pPos = (ScAddress*) aNotePosList.GetObject( nNoteStart+nCount ); 1913 if (pPos) 1914 { 1915 ScBaseCell* pCell = pDoc->GetCell( *pPos); 1916 if( const ScPostIt* pNote = pCell->GetNote() ) 1917 { 1918 if(const EditTextObject *pEditText = pNote->GetEditTextObject()) 1919 pEditEngine->SetText(*pEditText); 1920 long nTextHeight = pEditEngine->GetTextHeight(); 1921 if ( nPosY + nTextHeight < aPageRect.Bottom() ) 1922 { 1923 if (bDoPrint) 1924 { 1925 pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 ); 1926 1927 String aMarkStr; 1928 pPos->Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() ); 1929 aMarkStr += ':'; 1930 1931 // Zellposition auch per EditEngine, damit die Position stimmt 1932 pEditEngine->SetText(aMarkStr); 1933 pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 ); 1934 } 1935 1936 if ( pLocationData ) 1937 { 1938 Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) ); 1939 pLocationData->AddNoteText( aTextRect, *pPos ); 1940 Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) ); 1941 pLocationData->AddNoteMark( aMarkRect, *pPos ); 1942 } 1943 1944 nPosY += nTextHeight; 1945 nPosY += 200; // Abstand 1946 ++nCount; 1947 bOk = sal_True; 1948 } 1949 } 1950 } 1951 } 1952 while (bOk); 1953 1954 return nCount; 1955 } 1956 1957 long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) 1958 { 1959 if ( nNoteStart >= (long) aNotePosList.Count() || !aTableParam.bNotes ) 1960 return 0; 1961 1962 if ( bDoPrint && bClearWin ) 1963 { 1964 //! mit PrintPage zusammenfassen !!! 1965 1966 Color aBackgroundColor( COL_WHITE ); 1967 if ( bUseStyleColor ) 1968 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor ); 1969 1970 pDev->SetMapMode(aOffsetMode); 1971 pDev->SetLineColor(); 1972 pDev->SetFillColor(aBackgroundColor); 1973 pDev->DrawRect(Rectangle(Point(), 1974 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom), 1975 (long)(aPageSize.Height() * nScaleY * 100 / nZoom)))); 1976 } 1977 1978 1979 // aPageRect auf linke / rechte Seiten anpassen 1980 1981 Rectangle aTempRect = Rectangle( Point(), aPageSize ); 1982 if (IsMirror(nPageNo)) 1983 { 1984 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom; 1985 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom; 1986 } 1987 else 1988 { 1989 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom; 1990 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom; 1991 } 1992 1993 if ( pPrinter && bDoPrint ) 1994 { 1995 DBG_ERROR( "StartPage does not exist anymore" ); 1996 // pPrinter->StartPage(); 1997 } 1998 1999 if ( bDoPrint || pLocationData ) 2000 { 2001 // Kopf- und Fusszeilen 2002 2003 if (aHdr.bEnable) 2004 { 2005 long nHeaderY = aPageRect.Top()-aHdr.nHeight; 2006 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData ); 2007 } 2008 if (aFtr.bEnable) 2009 { 2010 long nFooterY = aPageRect.Bottom()+aFtr.nDistance; 2011 PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData ); 2012 } 2013 } 2014 2015 long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData ); 2016 2017 if ( pPrinter && bDoPrint ) 2018 { 2019 DBG_ERROR( "EndPage does not exist anymore" ); 2020 // pPrinter->EndPage(); 2021 } 2022 2023 return nCount; 2024 } 2025 2026 void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, 2027 sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) 2028 { 2029 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); 2030 long nLayoutSign = bLayoutRTL ? -1 : 1; 2031 2032 // nPageNo is the page number within all sheets of one "start page" setting 2033 2034 if ( bClearWin && bDoPrint ) 2035 { 2036 // muss genau zum Zeichnen des Rahmens in preview.cxx passen !!! 2037 2038 Color aBackgroundColor( COL_WHITE ); 2039 if ( bUseStyleColor ) 2040 aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor ); 2041 2042 pDev->SetMapMode(aOffsetMode); 2043 pDev->SetLineColor(); 2044 pDev->SetFillColor(aBackgroundColor); 2045 pDev->DrawRect(Rectangle(Point(), 2046 Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom), 2047 (long)(aPageSize.Height() * nScaleY * 100 / nZoom)))); 2048 } 2049 2050 2051 // aPageRect auf linke / rechte Seiten anpassen 2052 2053 Rectangle aTempRect = Rectangle( Point(), aPageSize ); 2054 if (IsMirror(nPageNo)) 2055 { 2056 aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom; 2057 aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom; 2058 } 2059 else 2060 { 2061 aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom; 2062 aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom; 2063 } 2064 2065 if ( aAreaParam.bRepeatCol ) 2066 if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol ) 2067 nX1 = nRepeatEndCol + 1; 2068 sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol); 2069 if ( aAreaParam.bRepeatRow ) 2070 if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow ) 2071 nY1 = nRepeatEndRow + 1; 2072 sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow); 2073 2074 // use new object hide flags in SdrPaintView 2075 if(pDrawView) 2076 { 2077 pDrawView->setHideOle(!aTableParam.bObjects); 2078 pDrawView->setHideChart(!aTableParam.bCharts); 2079 pDrawView->setHideDraw(!aTableParam.bDrawings); 2080 pDrawView->setHideFormControl(!aTableParam.bDrawings); 2081 } 2082 2083 if ( pPrinter && bDoPrint ) 2084 { 2085 DBG_ERROR( "StartPage does not exist anymore" ); 2086 // pPrinter->StartPage(); 2087 } 2088 2089 // Kopf- und Fusszeilen (ohne Zentrierung) 2090 2091 if (aHdr.bEnable) 2092 { 2093 long nHeaderY = aPageRect.Top()-aHdr.nHeight; 2094 PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData ); 2095 } 2096 if (aFtr.bEnable) 2097 { 2098 long nFooterY = aPageRect.Bottom()+aFtr.nDistance; 2099 PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData ); 2100 } 2101 2102 // Position ( Raender / zentrieren ) 2103 2104 long nLeftSpace = aPageRect.Left(); // Document-Twips 2105 long nTopSpace = aPageRect.Top(); 2106 if ( bCenterHor || bLayoutRTL ) 2107 { 2108 long nDataWidth = 0; 2109 SCCOL i; 2110 for (i=nX1; i<=nX2; i++) 2111 nDataWidth += pDoc->GetColWidth( i,nPrintTab ); 2112 if (bDoRepCol) 2113 for (i=nRepeatStartCol; i<=nRepeatEndCol; i++) 2114 nDataWidth += pDoc->GetColWidth( i,nPrintTab ); 2115 if (aTableParam.bHeaders) 2116 nDataWidth += (long) PRINT_HEADER_WIDTH; 2117 if (pBorderItem) 2118 nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) + 2119 pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width? 2120 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) 2121 nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) + 2122 pShadowItem->CalcShadowSpace(SHADOW_RIGHT); 2123 if ( bCenterHor ) 2124 { 2125 nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL 2126 if (pBorderItem) 2127 nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft()); 2128 } 2129 else if ( bLayoutRTL ) 2130 nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page 2131 } 2132 if ( bCenterVer ) 2133 { 2134 long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab); 2135 if (bDoRepRow) 2136 nDataHeight += pDoc->GetRowHeight( nRepeatStartRow, 2137 nRepeatEndRow, nPrintTab); 2138 if (aTableParam.bHeaders) 2139 nDataHeight += (long) PRINT_HEADER_HEIGHT; 2140 if (pBorderItem) 2141 nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) + 2142 pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width? 2143 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) 2144 nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) + 2145 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM); 2146 nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2; 2147 if (pBorderItem) 2148 nTopSpace -= lcl_LineTotal(pBorderItem->GetTop()); 2149 } 2150 2151 // calculate sizes of the elements for partitioning 2152 // (header, repeat, data) 2153 2154 long nHeaderWidth = 0; 2155 long nHeaderHeight = 0; 2156 long nRepeatWidth = 0; 2157 long nRepeatHeight = 0; 2158 long nContentWidth = 0; // scaled - not the same as nDataWidth above 2159 long nContentHeight = 0; 2160 if (aTableParam.bHeaders) 2161 { 2162 nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); 2163 nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); 2164 } 2165 if (bDoRepCol) 2166 for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++) 2167 nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); 2168 if (bDoRepRow) 2169 nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow, 2170 nRepeatEndRow, nPrintTab, nScaleY); 2171 for (SCCOL i=nX1; i<=nX2; i++) 2172 nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); 2173 nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, 2174 nScaleY); 2175 2176 // partition the page 2177 2178 long nStartX = ((long) ( nLeftSpace * nScaleX )); 2179 long nStartY = ((long) ( nTopSpace * nScaleY )); 2180 // nStartX -= aOffset.X(); // schon im MapMode 2181 // nStartY -= aOffset.Y(); 2182 2183 long nInnerStartX = nStartX; 2184 long nInnerStartY = nStartY; 2185 if (pBorderItem) 2186 { 2187 nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) + 2188 pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX ); 2189 nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) + 2190 pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY ); 2191 } 2192 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) 2193 { 2194 nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX ); 2195 nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY ); 2196 } 2197 2198 if ( bLayoutRTL ) 2199 { 2200 // arrange elements starting from the right edge 2201 nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth; 2202 2203 // make rounding easier so the elements are really next to each other in preview 2204 Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode ); 2205 long nOffsetOneX = aOffsetOnePixel.Width(); 2206 nInnerStartX += nOffsetOneX / 2; 2207 } 2208 2209 long nFrameStartX = nInnerStartX; 2210 long nFrameStartY = nInnerStartY; 2211 2212 long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used 2213 long nRepStartY = nInnerStartY + nHeaderHeight; 2214 long nDataX = nRepStartX + nRepeatWidth * nLayoutSign; 2215 long nDataY = nRepStartY + nRepeatHeight; 2216 long nEndX = nDataX + nContentWidth * nLayoutSign; 2217 long nEndY = nDataY + nContentHeight; 2218 long nFrameEndX = nEndX; 2219 long nFrameEndY = nEndY; 2220 2221 if ( bLayoutRTL ) 2222 { 2223 // each element's start position is its left edge 2224 //! subtract one pixel less? 2225 nInnerStartX -= nHeaderWidth; // used for header 2226 nRepStartX -= nRepeatWidth; 2227 nDataX -= nContentWidth; 2228 2229 // continue right of the main elements again 2230 nEndX += nHeaderWidth + nRepeatWidth + nContentWidth; 2231 } 2232 2233 // Seiten-Rahmen / Hintergrund 2234 2235 //! nEndX/Y anpassen 2236 2237 long nBorderEndX = nEndX; 2238 long nBorderEndY = nEndY; 2239 if (pBorderItem) 2240 { 2241 nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) + 2242 pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX ); 2243 nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) + 2244 pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY ); 2245 } 2246 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) 2247 { 2248 nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX ); 2249 nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY ); 2250 } 2251 2252 if ( bDoPrint ) 2253 { 2254 pDev->SetMapMode( aOffsetMode ); 2255 DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY, 2256 pBorderItem, pBackgroundItem, pShadowItem ); 2257 2258 pDev->SetMapMode( aTwipMode ); 2259 } 2260 2261 pDev->SetMapMode( aOffsetMode ); 2262 2263 // Wiederholungszeilen/Spalten ausgeben 2264 2265 if (bDoRepCol && bDoRepRow) 2266 { 2267 if ( bDoPrint ) 2268 PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow, 2269 nRepStartX,nRepStartY, sal_True,sal_True,sal_False,sal_False ); 2270 if ( pLocationData ) 2271 LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow, 2272 nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData ); 2273 } 2274 if (bDoRepCol) 2275 { 2276 if ( bDoPrint ) 2277 PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, 2278 sal_True,!bDoRepRow,sal_False,sal_True ); 2279 if ( pLocationData ) 2280 LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,sal_False, *pLocationData ); 2281 } 2282 if (bDoRepRow) 2283 { 2284 if ( bDoPrint ) 2285 PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, 2286 !bDoRepCol,sal_True,sal_True,sal_False ); 2287 if ( pLocationData ) 2288 LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, sal_False,sal_True, *pLocationData ); 2289 } 2290 2291 // Daten ausgeben 2292 2293 if ( bDoPrint ) 2294 PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True ); 2295 if ( pLocationData ) 2296 LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, sal_False,sal_False, *pLocationData ); 2297 2298 // Spalten-/Zeilenkoepfe ausgeben 2299 // nach den Daten (ueber evtl. weitergezeichneten Schatten) 2300 2301 Color aGridColor( COL_BLACK ); 2302 if ( bUseStyleColor ) 2303 aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); 2304 2305 if (aTableParam.bHeaders) 2306 { 2307 if ( bDoPrint ) 2308 { 2309 pDev->SetLineColor( aGridColor ); 2310 pDev->SetFillColor(); 2311 pDev->SetMapMode(aOffsetMode); 2312 } 2313 2314 ScPatternAttr aPattern( pDoc->GetPool() ); 2315 Font aFont; 2316 ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT; 2317 aPattern.GetFont( aFont, eColorMode, pDev ); 2318 pDev->SetFont( aFont ); 2319 2320 if (bDoRepCol) 2321 { 2322 if ( bDoPrint ) 2323 PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY ); 2324 if ( pLocationData ) 2325 LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData ); 2326 } 2327 if ( bDoPrint ) 2328 PrintColHdr( nX1,nX2, nDataX,nInnerStartY ); 2329 if ( pLocationData ) 2330 LocateColHdr( nX1,nX2, nDataX,nInnerStartY, sal_False, *pLocationData ); 2331 if (bDoRepRow) 2332 { 2333 if ( bDoPrint ) 2334 PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY ); 2335 if ( pLocationData ) 2336 LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData ); 2337 } 2338 if ( bDoPrint ) 2339 PrintRowHdr( nY1,nY2, nInnerStartX,nDataY ); 2340 if ( pLocationData ) 2341 LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, sal_False, *pLocationData ); 2342 } 2343 2344 // einfacher Rahmen 2345 2346 if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) ) 2347 { 2348 Size aOnePixel = pDev->PixelToLogic(Size(1,1)); 2349 long nOneX = aOnePixel.Width(); 2350 long nOneY = aOnePixel.Height(); 2351 2352 long nLeftX = nFrameStartX; 2353 long nTopY = nFrameStartY - nOneY; 2354 long nRightX = nFrameEndX; 2355 long nBottomY = nFrameEndY - nOneY; 2356 if ( !bLayoutRTL ) 2357 { 2358 nLeftX -= nOneX; 2359 nRightX -= nOneX; 2360 } 2361 pDev->SetMapMode(aOffsetMode); 2362 pDev->SetLineColor( aGridColor ); 2363 pDev->SetFillColor(); 2364 pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) ); 2365 // nEndX/Y ohne Rahmen-Anpassung 2366 } 2367 2368 if ( pPrinter && bDoPrint ) 2369 { 2370 DBG_ERROR( "EndPage does not exist anymore" ); 2371 // pPrinter->EndPage(); 2372 } 2373 2374 aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab ); 2375 bSourceRangeValid = sal_True; 2376 } 2377 2378 void ScPrintFunc::SetOffset( const Point& rOfs ) 2379 { 2380 aSrcOffset = rOfs; 2381 } 2382 2383 void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom ) 2384 { 2385 nManualZoom = nNewZoom; 2386 } 2387 2388 void ScPrintFunc::SetClearFlag( sal_Bool bFlag ) 2389 { 2390 bClearWin = bFlag; 2391 } 2392 2393 void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag ) 2394 { 2395 bUseStyleColor = bFlag; 2396 if (pEditEngine) 2397 pEditEngine->EnableAutoColor( bUseStyleColor ); 2398 } 2399 2400 void ScPrintFunc::SetRenderFlag( sal_Bool bFlag ) 2401 { 2402 bIsRender = bFlag; // set when using XRenderable (PDF) 2403 } 2404 2405 void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects() 2406 { 2407 aTableParam.bCellContent = false; 2408 aTableParam.bNotes = false; 2409 aTableParam.bGrid = false; 2410 aTableParam.bHeaders = false; 2411 aTableParam.bFormulas = false; 2412 aTableParam.bNullVals = false; 2413 } 2414 2415 // 2416 // UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige 2417 // richtig zu setzen - immer ohne UserArea 2418 // 2419 2420 sal_Bool ScPrintFunc::UpdatePages() 2421 { 2422 if (!pParamSet) 2423 return sal_False; 2424 2425 // Zoom 2426 2427 nZoom = 100; 2428 if (aTableParam.bScalePageNum || aTableParam.bScaleTo) 2429 nZoom = ZOOM_MIN; // stimmt fuer Umbrueche 2430 else if (aTableParam.bScaleAll) 2431 { 2432 nZoom = aTableParam.nScaleAll; 2433 if ( nZoom <= ZOOM_MIN ) 2434 nZoom = ZOOM_MIN; 2435 } 2436 2437 String aName = pDoc->GetPageStyle( nPrintTab ); 2438 SCTAB nTabCount = pDoc->GetTableCount(); 2439 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 2440 if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName ) 2441 { 2442 // Wiederholungszeilen / Spalten 2443 pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow ); 2444 2445 // Umbrueche setzen 2446 ResetBreaks(nTab); 2447 pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID); 2448 } 2449 2450 return sal_True; 2451 } 2452 2453 long ScPrintFunc::CountPages() // setzt auch nPagesX, nPagesY 2454 { 2455 sal_Bool bAreaOk = sal_False; 2456 2457 if (pDoc->HasTable( nPrintTab )) 2458 { 2459 if (aAreaParam.bPrintArea) // Druckbereich angegeben? 2460 { 2461 if ( bPrintCurrentTable ) 2462 { 2463 ScRange& rRange = aAreaParam.aPrintArea; 2464 2465 // hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle 2466 // wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim 2467 // Einfuegen von Tabellen etc. angepasst werden ! 2468 2469 nStartCol = rRange.aStart.Col(); 2470 nStartRow = rRange.aStart.Row(); 2471 nEndCol = rRange.aEnd .Col(); 2472 nEndRow = rRange.aEnd .Row(); 2473 bAreaOk = AdjustPrintArea(sal_False); // begrenzen 2474 } 2475 else 2476 bAreaOk = sal_False; 2477 } 2478 else // aus Dokument suchen 2479 bAreaOk = AdjustPrintArea(sal_True); 2480 } 2481 2482 if (bAreaOk) 2483 { 2484 long nPages = 0; 2485 size_t nY; 2486 if (bMultiArea) 2487 { 2488 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab ); 2489 for (sal_uInt16 i=0; i<nRCount; i++) 2490 { 2491 CalcZoom(i); 2492 if ( aTableParam.bSkipEmpty ) 2493 for (nY=0; nY<nPagesY; nY++) 2494 nPages += pPageRows[nY].CountVisible(); 2495 else 2496 nPages += ((long) nPagesX) * nPagesY; 2497 if ( pPageData ) 2498 FillPageData(); 2499 } 2500 } 2501 else 2502 { 2503 CalcZoom(RANGENO_NORANGE); // Zoom berechnen 2504 if ( aTableParam.bSkipEmpty ) 2505 for (nY=0; nY<nPagesY; nY++) 2506 nPages += pPageRows[nY].CountVisible(); 2507 else 2508 nPages += ((long) nPagesX) * nPagesY; 2509 if ( pPageData ) 2510 FillPageData(); 2511 } 2512 return nPages; 2513 } 2514 else 2515 { 2516 // nZoom = 100; // nZoom auf letztem Wert stehenlassen !!! 2517 nPagesX = nPagesY = nTotalY = 0; 2518 return 0; 2519 } 2520 } 2521 2522 long ScPrintFunc::CountNotePages() 2523 { 2524 if ( !aTableParam.bNotes || !bPrintCurrentTable ) 2525 return 0; 2526 2527 long nCount=0; 2528 SCCOL nCol; 2529 SCROW nRow; 2530 2531 sal_Bool bError = sal_False; 2532 if (!aAreaParam.bPrintArea) 2533 bError = !AdjustPrintArea(sal_True); // komplett aus Dok suchen 2534 2535 sal_uInt16 nRepeats = 1; // wie oft durchgehen ? 2536 if (bMultiArea) 2537 nRepeats = pDoc->GetPrintRangeCount(nPrintTab); 2538 if (bError) 2539 nRepeats = 0; 2540 2541 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++) 2542 { 2543 sal_Bool bDoThis = sal_True; 2544 if (bMultiArea) // alle Areas durchgehen 2545 { 2546 const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep ); 2547 if ( pThisRange ) 2548 { 2549 nStartCol = pThisRange->aStart.Col(); 2550 nStartRow = pThisRange->aStart.Row(); 2551 nEndCol = pThisRange->aEnd .Col(); 2552 nEndRow = pThisRange->aEnd .Row(); 2553 bDoThis = AdjustPrintArea(sal_False); 2554 } 2555 } 2556 2557 if (bDoThis) 2558 { 2559 ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow ); 2560 ScBaseCell* pCell = aIter.GetNext( nCol, nRow ); 2561 while (pCell) 2562 { 2563 if (pCell->HasNote()) 2564 { 2565 aNotePosList.Insert( new ScAddress( nCol,nRow,nPrintTab ), LIST_APPEND ); 2566 ++nCount; 2567 } 2568 2569 pCell = aIter.GetNext( nCol, nRow ); 2570 } 2571 } 2572 } 2573 2574 long nPages = 0; 2575 long nNoteNr = 0; 2576 long nNoteAdd; 2577 do 2578 { 2579 nNoteAdd = PrintNotes( nPages, nNoteNr, sal_False, NULL ); 2580 if (nNoteAdd) 2581 { 2582 nNoteNr += nNoteAdd; 2583 ++nPages; 2584 } 2585 } 2586 while (nNoteAdd); 2587 2588 return nPages; 2589 } 2590 2591 void ScPrintFunc::InitModes() // aus nZoom etc. die MapModes setzen 2592 { 2593 aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom ); 2594 2595 long nEffZoom = nZoom * (long) nManualZoom; 2596 2597 // nScaleX = nScaleY = 1.0; // Ausgabe in Twips 2598 nScaleX = nScaleY = HMM_PER_TWIPS; // Ausgabe in 1/100 mm 2599 2600 Fraction aZoomFract( nEffZoom,10000 ); 2601 Fraction aHorFract = aZoomFract; 2602 2603 if ( !pPrinter && !bIsRender ) // adjust scale for preview 2604 { 2605 double nFact = pDocShell->GetOutputFactor(); 2606 aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 ); 2607 } 2608 2609 aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract ); 2610 2611 Point aLogicOfs( -aOffset.X(), -aOffset.Y() ); 2612 aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract ); 2613 2614 Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) ); 2615 aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract ); 2616 } 2617 2618 //-------------------------------------------------------------------- 2619 2620 void ScPrintFunc::ApplyPrintSettings() 2621 { 2622 if ( pPrinter ) 2623 { 2624 // 2625 // Printer zum Drucken umstellen 2626 // 2627 2628 Size aEnumSize = aPageSize; 2629 2630 2631 pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT ); 2632 if ( bLandscape ) 2633 { 2634 // landscape is always interpreted as a rotation by 90 degrees ! 2635 // this leads to non WYSIWIG but at least it prints! 2636 // #i21775# 2637 long nTemp = aEnumSize.Width(); 2638 aEnumSize.Width() = aEnumSize.Height(); 2639 aEnumSize.Height() = nTemp; 2640 } 2641 Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True ); 2642 sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue(); 2643 2644 pPrinter->SetPaper( ePaper ); 2645 if ( PAPER_USER == ePaper ) 2646 { 2647 MapMode aPrinterMode = pPrinter->GetMapMode(); 2648 MapMode aLocalMode( MAP_TWIP ); 2649 pPrinter->SetMapMode( aLocalMode ); 2650 pPrinter->SetPaperSizeUser( aEnumSize ); 2651 pPrinter->SetMapMode( aPrinterMode ); 2652 } 2653 2654 pPrinter->SetPaperBin( nPaperBin ); 2655 } 2656 } 2657 2658 //-------------------------------------------------------------------- 2659 // rPageRanges = Range fuer alle Tabellen 2660 // nStartPage = in rPageRanges beginnen bei nStartPage 2661 // nDisplayStart = lfd. Nummer fuer Anzeige der Seitennummer 2662 2663 long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, 2664 long nStartPage, long nDisplayStart, sal_Bool bDoPrint, 2665 ScPreviewLocationData* pLocationData ) 2666 { 2667 DBG_ASSERT(pDev,"Device == NULL"); 2668 if (!pParamSet) 2669 return 0; 2670 2671 if ( pPrinter && bDoPrint ) 2672 ApplyPrintSettings(); 2673 2674 //-------------------------------------------------------------------- 2675 2676 InitModes(); 2677 if ( pLocationData ) 2678 { 2679 pLocationData->SetCellMapMode( aOffsetMode ); 2680 pLocationData->SetPrintTab( nPrintTab ); 2681 } 2682 2683 MakeTableString(); 2684 2685 //-------------------------------------------------------------------- 2686 2687 long nPageNo = 0; 2688 long nPrinted = 0; 2689 long nEndPage = rPageRanges.GetTotalRange().Max(); 2690 2691 sal_uInt16 nRepeats = 1; // wie oft durchgehen ? 2692 if (bMultiArea) 2693 nRepeats = pDoc->GetPrintRangeCount(nPrintTab); 2694 for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++) 2695 { 2696 if (bMultiArea) // Bereich neu belegen ? 2697 { 2698 CalcZoom(nStep); // setzt auch nStartCol etc. neu 2699 InitModes(); 2700 } 2701 2702 SCCOL nX1; 2703 SCROW nY1; 2704 SCCOL nX2; 2705 SCROW nY2; 2706 size_t nCountX; 2707 size_t nCountY; 2708 2709 if (aTableParam.bTopDown) // von oben nach unten 2710 { 2711 nX1 = nStartCol; 2712 for (nCountX=0; nCountX<nPagesX; nCountX++) 2713 { 2714 nX2 = pPageEndX[nCountX]; 2715 for (nCountY=0; nCountY<nPagesY; nCountY++) 2716 { 2717 nY1 = pPageRows[nCountY].GetStartRow(); 2718 nY2 = pPageRows[nCountY].GetEndRow(); 2719 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) ) 2720 { 2721 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) 2722 { 2723 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, 2724 bDoPrint, pLocationData ); 2725 ++nPrinted; 2726 } 2727 ++nPageNo; 2728 } 2729 } 2730 nX1 = nX2 + 1; 2731 } 2732 } 2733 else // von links nach rechts 2734 { 2735 for (nCountY=0; nCountY<nPagesY; nCountY++) 2736 { 2737 nY1 = pPageRows[nCountY].GetStartRow(); 2738 nY2 = pPageRows[nCountY].GetEndRow(); 2739 nX1 = nStartCol; 2740 for (nCountX=0; nCountX<nPagesX; nCountX++) 2741 { 2742 nX2 = pPageEndX[nCountX]; 2743 if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) ) 2744 { 2745 if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) 2746 { 2747 PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, 2748 bDoPrint, pLocationData ); 2749 ++nPrinted; 2750 } 2751 ++nPageNo; 2752 } 2753 nX1 = nX2 + 1; 2754 } 2755 } 2756 } 2757 } 2758 2759 aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES ); 2760 2761 long nNoteNr = 0; 2762 long nNoteAdd; 2763 do 2764 { 2765 if ( nPageNo+nStartPage <= nEndPage ) 2766 { 2767 sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 ); 2768 nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected, 2769 ( bPageSelected ? pLocationData : NULL ) ); 2770 if ( nNoteAdd ) 2771 { 2772 nNoteNr += nNoteAdd; 2773 if (bPageSelected) 2774 { 2775 ++nPrinted; 2776 bSourceRangeValid = sal_False; // last page was no cell range 2777 } 2778 ++nPageNo; 2779 } 2780 } 2781 else 2782 nNoteAdd = 0; 2783 } 2784 while (nNoteAdd); 2785 2786 if ( bMultiArea ) 2787 ResetBreaks(nPrintTab); // Breaks fuer Anzeige richtig 2788 2789 return nPrinted; 2790 } 2791 2792 void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // Zoom berechnen 2793 { 2794 sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab ); 2795 const ScRange* pThisRange = NULL; 2796 if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount ) 2797 pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo ); 2798 if ( pThisRange ) 2799 { 2800 nStartCol = pThisRange->aStart.Col(); 2801 nStartRow = pThisRange->aStart.Row(); 2802 nEndCol = pThisRange->aEnd .Col(); 2803 nEndRow = pThisRange->aEnd .Row(); 2804 } 2805 2806 if (!AdjustPrintArea(sal_False)) // leer 2807 { 2808 nZoom = 100; 2809 nPagesX = nPagesY = nTotalY = 0; 2810 return; 2811 } 2812 2813 pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow ); 2814 2815 if (aTableParam.bScalePageNum) 2816 { 2817 nZoom = 100; 2818 sal_uInt16 nPagesToFit = aTableParam.nScalePageNum; 2819 2820 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; 2821 while (true) 2822 { 2823 if (nZoom <= ZOOM_MIN) 2824 break; 2825 2826 CalcPages(); 2827 bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit); 2828 2829 if (bFitsPage) 2830 { 2831 if (nZoom == 100) 2832 // If it fits at 100 %, it's good enough for me. 2833 break; 2834 2835 nLastFitZoom = nZoom; 2836 nZoom = (nLastNonFitZoom + nZoom) / 2; 2837 2838 if (nLastFitZoom == nZoom) 2839 // It converged. Use this zoom level. 2840 break; 2841 } 2842 else 2843 { 2844 if (nZoom - nLastFitZoom <= 1) 2845 { 2846 nZoom = nLastFitZoom; 2847 CalcPages(); 2848 break; 2849 } 2850 2851 nLastNonFitZoom = nZoom; 2852 nZoom = (nLastFitZoom + nZoom) / 2; 2853 } 2854 } 2855 } 2856 else if (aTableParam.bScaleTo) 2857 { 2858 nZoom = 100; 2859 sal_uInt16 nW = aTableParam.nScaleWidth; 2860 sal_uInt16 nH = aTableParam.nScaleHeight; 2861 2862 sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; 2863 while (true) 2864 { 2865 if (nZoom <= ZOOM_MIN) 2866 break; 2867 2868 CalcPages(); 2869 bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))); 2870 2871 if (bFitsPage) 2872 { 2873 if (nZoom == 100) 2874 // If it fits at 100 %, it's good enough for me. 2875 break; 2876 2877 nLastFitZoom = nZoom; 2878 nZoom = (nLastNonFitZoom + nZoom) / 2; 2879 2880 if (nLastFitZoom == nZoom) 2881 // It converged. Use this zoom level. 2882 break; 2883 } 2884 else 2885 { 2886 if (nZoom - nLastFitZoom <= 1) 2887 { 2888 nZoom = nLastFitZoom; 2889 CalcPages(); 2890 break; 2891 } 2892 2893 nLastNonFitZoom = nZoom; 2894 nZoom = (nLastFitZoom + nZoom) / 2; 2895 } 2896 } 2897 } 2898 else if (aTableParam.bScaleAll) 2899 { 2900 nZoom = aTableParam.nScaleAll; 2901 if ( nZoom <= ZOOM_MIN ) 2902 nZoom = ZOOM_MIN; 2903 CalcPages(); 2904 } 2905 else 2906 { 2907 DBG_ASSERT( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" ); 2908 nZoom = 100; 2909 CalcPages(); 2910 } 2911 } 2912 2913 Size ScPrintFunc::GetDocPageSize() 2914 { 2915 // Hoehe Kopf-/Fusszeile anpassen 2916 2917 InitModes(); // aTwipMode aus nZoom initialisieren 2918 pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips 2919 UpdateHFHeight( aHdr ); 2920 UpdateHFHeight( aFtr ); 2921 2922 // Seitengroesse in Document-Twips 2923 // Berechnung Left / Right auch in PrintPage 2924 2925 aPageRect = Rectangle( Point(), aPageSize ); 2926 aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom; 2927 aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom; 2928 aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight; 2929 aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight; 2930 2931 Size aDocPageSize = aPageRect.GetSize(); 2932 if (aTableParam.bHeaders) 2933 { 2934 aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH; 2935 aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT; 2936 } 2937 if (pBorderItem) 2938 { 2939 aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) + 2940 lcl_LineTotal(pBorderItem->GetRight()) + 2941 pBorderItem->GetDistance(BOX_LINE_LEFT) + 2942 pBorderItem->GetDistance(BOX_LINE_RIGHT); 2943 aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) + 2944 lcl_LineTotal(pBorderItem->GetBottom()) + 2945 pBorderItem->GetDistance(BOX_LINE_TOP) + 2946 pBorderItem->GetDistance(BOX_LINE_BOTTOM); 2947 } 2948 if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) 2949 { 2950 aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) + 2951 pShadowItem->CalcShadowSpace(SHADOW_RIGHT); 2952 aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) + 2953 pShadowItem->CalcShadowSpace(SHADOW_BOTTOM); 2954 } 2955 return aDocPageSize; 2956 } 2957 2958 void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Breaks fuer Anzeige richtig setzen 2959 { 2960 pDoc->SetPageSize( nTab, GetDocPageSize() ); 2961 pDoc->UpdatePageBreaks( nTab, NULL ); 2962 } 2963 2964 void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry, 2965 SCCOL nStartCol, const SCCOL* pPageEndX ) 2966 { 2967 size_t nPagesX = rPageRowEntry.GetPagesX(); 2968 SCROW nStartRow = rPageRowEntry.GetStartRow(); 2969 SCROW nEndRow = rPageRowEntry.GetEndRow(); 2970 2971 sal_Bool bLeftIsEmpty = sal_False; 2972 ScRange aTempRange; 2973 Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 ); 2974 2975 for (size_t i=0; i<nPagesX; i++) 2976 { 2977 SCCOL nEndCol = pPageEndX[i]; 2978 if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow, 2979 bLeftIsEmpty, &aTempRange, &aTempRect ) ) 2980 { 2981 rPageRowEntry.SetHidden(i); 2982 bLeftIsEmpty = sal_True; 2983 } 2984 else 2985 bLeftIsEmpty = sal_False; 2986 2987 nStartCol = nEndCol+1; 2988 } 2989 } 2990 2991 void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom 2992 { 2993 if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1]; 2994 //performance impact 2995 // if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1]; 2996 // if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! vorher zaehlen !!!! 2997 2998 pDoc->SetPageSize( nPrintTab, GetDocPageSize() ); 2999 if (aAreaParam.bPrintArea) 3000 { 3001 ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab ); 3002 pDoc->UpdatePageBreaks( nPrintTab, &aRange ); 3003 } 3004 else 3005 pDoc->UpdatePageBreaks( nPrintTab, NULL ); // sonst wird das Ende markiert 3006 SCROW nRealCnt = nEndRow-nStartRow+1; 3007 if (!pPageEndY) pPageEndY = new SCROW[nRealCnt+1]; 3008 if (!pPageRows) pPageRows = new ScPageRowEntry[nRealCnt+1]; //! vorher zaehlen !!!! 3009 // 3010 // Seiteneinteilung nach Umbruechen in Col/RowFlags 3011 // Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer. 3012 // 3013 3014 nPagesX = 0; 3015 nPagesY = 0; 3016 nTotalY = 0; 3017 3018 bool bVisCol = false; 3019 SCCOL nLastCol = -1; 3020 for (SCCOL i=nStartCol; i<=nEndCol; i++) 3021 { 3022 bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol); 3023 bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE); 3024 if ( i>nStartCol && bVisCol && bPageBreak ) 3025 { 3026 pPageEndX[nPagesX] = i-1; 3027 ++nPagesX; 3028 bVisCol = false; 3029 } 3030 if (!bHidden) 3031 bVisCol = true; 3032 } 3033 if (bVisCol) // auch am Ende keine leeren Seiten 3034 { 3035 pPageEndX[nPagesX] = nEndCol; 3036 ++nPagesX; 3037 } 3038 3039 bool bVisRow = false; 3040 SCROW nPageStartRow = nStartRow; 3041 SCROW nLastVisibleRow = -1; 3042 3043 ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab)); 3044 SCROW nNextPageBreak = pRowBreakIter->first(); 3045 while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow) 3046 // Skip until the page break position is at the start row or greater. 3047 nNextPageBreak = pRowBreakIter->next(); 3048 3049 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) 3050 { 3051 bool bPageBreak = (nNextPageBreak == nRow); 3052 if (bPageBreak) 3053 nNextPageBreak = pRowBreakIter->next(); 3054 3055 if (nRow > nStartRow && bVisRow && bPageBreak ) 3056 { 3057 pPageEndY[nTotalY] = nRow-1; 3058 ++nTotalY; 3059 3060 if ( !aTableParam.bSkipEmpty || 3061 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) ) 3062 { 3063 pPageRows[nPagesY].SetStartRow( nPageStartRow ); 3064 pPageRows[nPagesY].SetEndRow( nRow-1 ); 3065 pPageRows[nPagesY].SetPagesX( nPagesX ); 3066 if (aTableParam.bSkipEmpty) 3067 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); 3068 ++nPagesY; 3069 } 3070 3071 nPageStartRow = nRow; 3072 bVisRow = false; 3073 } 3074 3075 if (nRow <= nLastVisibleRow) 3076 { 3077 // This row is still visible. Don't bother calling RowHidden() to 3078 // find out, for speed optimization. 3079 bVisRow = true; 3080 continue; 3081 } 3082 3083 SCROW nLastRow = -1; 3084 if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow)) 3085 { 3086 bVisRow = true; 3087 nLastVisibleRow = nLastRow; 3088 } 3089 else 3090 // skip all hidden rows. 3091 nRow = nLastRow; 3092 } 3093 3094 if (bVisRow) 3095 { 3096 pPageEndY[nTotalY] = nEndRow; 3097 ++nTotalY; 3098 3099 if ( !aTableParam.bSkipEmpty || 3100 !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) ) 3101 { 3102 pPageRows[nPagesY].SetStartRow( nPageStartRow ); 3103 pPageRows[nPagesY].SetEndRow( nEndRow ); 3104 pPageRows[nPagesY].SetPagesX( nPagesX ); 3105 if (aTableParam.bSkipEmpty) 3106 lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); 3107 ++nPagesY; 3108 } 3109 } 3110 } 3111 3112 //------------------------------------------------------------------------ 3113 // class ScJobSetup 3114 //------------------------------------------------------------------------ 3115 3116 ScJobSetup::ScJobSetup( SfxPrinter* pPrinter ) 3117 { 3118 eOrientation = pPrinter->GetOrientation(); 3119 nPaperBin = pPrinter->GetPaperBin(); 3120 ePaper = pPrinter->GetPaper(); 3121 3122 if ( PAPER_USER == ePaper ) 3123 { 3124 aUserSize = pPrinter->GetPaperSize(); 3125 aUserMapMode = pPrinter->GetMapMode(); 3126 } 3127 }; 3128 3129 3130 3131 3132 3133