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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_svx.hxx" 24 25 #include <vcl/bitmap.hxx> 26 #include <editeng/frmdiritem.hxx> 27 #include <svx/pageitem.hxx> 28 #include <svx/pagectrl.hxx> 29 #include <editeng/boxitem.hxx> 30 #include <algorithm> 31 #include <basegfx/matrix/b2dhommatrix.hxx> 32 #include <drawinglayer/geometry/viewinformation2d.hxx> 33 #include <drawinglayer/processor2d/processor2dtools.hxx> 34 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 35 #include <basegfx/polygon/b2dpolygontools.hxx> 36 37 // STATIC DATA ----------------------------------------------------------- 38 39 #define CELL_WIDTH 1600L 40 #define CELL_HEIGHT 800L 41 42 // class SvxPageWindow --------------------------------------------------- 43 44 SvxPageWindow::SvxPageWindow(Window* pParent,const ResId& rId) 45 : Window(pParent,rId), 46 aWinSize(), 47 aSize(), 48 49 nTop(0), 50 nBottom(0), 51 nLeft(0), 52 nRight(0), 53 54 //UUUU 55 pBorder(0), 56 bResetBackground(sal_False), 57 bFrameDirection(sal_False), 58 nFrameDirection(0), 59 60 nHdLeft(0), 61 nHdRight(0), 62 nHdDist(0), 63 nHdHeight(0), 64 65 pHdBorder(0), 66 nFtLeft(0), 67 nFtRight(0), 68 nFtDist(0), 69 nFtHeight(0), 70 71 pFtBorder(0), 72 73 maHeaderFillAttributes(), 74 maFooterFillAttributes(), 75 maPageFillAttributes(), 76 77 bFooter(sal_False), 78 bHeader(sal_False), 79 bTable(sal_False), 80 bHorz(sal_False), 81 bVert(sal_False), 82 eUsage(SVX_PAGE_ALL), 83 84 aLeftText(), 85 aRightText() 86 87 { 88 // defaultmaessing in Twips rechnen 89 SetMapMode(MapMode(MAP_TWIP)); 90 aWinSize = GetOutputSizePixel(); 91 aWinSize.Height() -= 4; 92 aWinSize.Width() -= 4; 93 94 aWinSize = PixelToLogic(aWinSize); 95 SetBackground(); 96 } 97 98 // ----------------------------------------------------------------------- 99 100 SvxPageWindow::~SvxPageWindow() 101 { 102 delete pHdBorder; 103 delete pFtBorder; 104 } 105 106 // ----------------------------------------------------------------------- 107 108 void __EXPORT SvxPageWindow::Paint(const Rectangle&) 109 { 110 Fraction aXScale(aWinSize.Width(),std::max((long)(aSize.Width() * 2 + aSize.Width() / 8),1L)); 111 Fraction aYScale(aWinSize.Height(),std::max(aSize.Height(),1L)); 112 MapMode aMapMode(GetMapMode()); 113 114 if(aYScale < aXScale) 115 { 116 aMapMode.SetScaleX(aYScale); 117 aMapMode.SetScaleY(aYScale); 118 } 119 else 120 { 121 aMapMode.SetScaleX(aXScale); 122 aMapMode.SetScaleY(aXScale); 123 } 124 SetMapMode(aMapMode); 125 Size aSz(PixelToLogic(GetSizePixel())); 126 long nYPos = (aSz.Height() - aSize.Height()) / 2; 127 128 if(eUsage == SVX_PAGE_ALL) 129 { 130 // alle Seiten gleich -> eine Seite malen 131 if(aSize.Width() > aSize.Height()) 132 { 133 // Querformat in gleicher Gr"osse zeichnen 134 Fraction aX = aMapMode.GetScaleX(); 135 Fraction aY = aMapMode.GetScaleY(); 136 Fraction a2(1.5); 137 aX *= a2; 138 aY *= a2; 139 aMapMode.SetScaleX(aX); 140 aMapMode.SetScaleY(aY); 141 SetMapMode(aMapMode); 142 aSz = PixelToLogic(GetSizePixel()); 143 nYPos = (aSz.Height() - aSize.Height()) / 2; 144 long nXPos = (aSz.Width() - aSize.Width()) / 2; 145 DrawPage(Point(nXPos,nYPos),sal_True,sal_True); 146 } 147 else 148 // Hochformat 149 DrawPage(Point((aSz.Width() - aSize.Width()) / 2,nYPos),sal_True,sal_True); 150 } 151 else 152 { 153 // Linke und rechte Seite unterschiedlich -> ggf. zwei Seiten malen 154 DrawPage(Point(0,nYPos),sal_False,(sal_Bool)(eUsage & SVX_PAGE_LEFT)); 155 DrawPage(Point(aSize.Width() + aSize.Width() / 8,nYPos),sal_True, 156 (sal_Bool)(eUsage & SVX_PAGE_RIGHT)); 157 } 158 } 159 160 // ----------------------------------------------------------------------- 161 void SvxPageWindow::DrawPage(const Point& rOrg,const sal_Bool bSecond,const sal_Bool bEnabled) 162 { 163 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 164 const Color& rFieldColor = rStyleSettings.GetFieldColor(); 165 const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor(); 166 const Color& rDisableColor = rStyleSettings.GetDisableColor(); 167 const Color& rDlgColor = rStyleSettings.GetDialogColor(); 168 169 // background 170 if(!bSecond || bResetBackground) 171 { 172 SetLineColor(Color(COL_TRANSPARENT)); 173 SetFillColor(rDlgColor); 174 Size winSize(GetOutputSize()); 175 DrawRect(Rectangle(Point(0,0),winSize)); 176 177 if(bResetBackground) 178 bResetBackground = sal_False; 179 } 180 SetLineColor(rFieldTextColor); 181 // Schatten 182 Size aTempSize = aSize; 183 // Seite 184 if(!bEnabled) 185 { 186 SetFillColor(rDisableColor); 187 DrawRect(Rectangle(rOrg,aTempSize)); 188 return; 189 } 190 SetFillColor(rFieldColor); 191 DrawRect(Rectangle(rOrg,aTempSize)); 192 193 // Border Top Bottom Left Right 194 Point aBegin(rOrg); 195 Point aEnd(rOrg); 196 197 long nL = nLeft; 198 long nR = nRight; 199 200 if(eUsage == SVX_PAGE_MIRROR && !bSecond) 201 { 202 // f"ur gespiegelt drehen 203 nL = nRight; 204 nR = nLeft; 205 } 206 207 Rectangle aRect; 208 209 aRect.Left() = rOrg.X() + nL; 210 aRect.Right() = rOrg.X() + aTempSize.Width() - nR; 211 aRect.Top() = rOrg.Y() + nTop; 212 aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom; 213 214 Rectangle aHdRect(aRect); 215 Rectangle aFtRect(aRect); 216 217 if(bHeader || bFooter) 218 { 219 //UUUU Header and/or footer used 220 const Color aLineColor(GetLineColor()); 221 222 //UUUU draw PageFill first and on the whole page, no outline 223 SetLineColor(); 224 drawFillAttributes(maPageFillAttributes, aRect, aRect); 225 SetLineColor(aLineColor); 226 227 if(bHeader) 228 { 229 // ggf. Header anzeigen 230 aHdRect.Left() += nHdLeft; 231 aHdRect.Right() -= nHdRight; 232 aHdRect.Bottom() = aRect.Top() + nHdHeight; 233 aRect.Top() += nHdHeight + nHdDist; 234 235 // draw header over PageFill, plus outline 236 drawFillAttributes(maHeaderFillAttributes, aHdRect, aHdRect); 237 } 238 239 if(bFooter) 240 { 241 // ggf. Footer anzeigen 242 aFtRect.Left() += nFtLeft; 243 aFtRect.Right() -= nFtRight; 244 aFtRect.Top() = aRect.Bottom() - nFtHeight; 245 aRect.Bottom() -= nFtHeight + nFtDist; 246 247 // draw footer over PageFill, plus outline 248 drawFillAttributes(maFooterFillAttributes, aFtRect, aFtRect); 249 } 250 251 // draw page's reduced outline, only outline 252 drawFillAttributes(drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect); 253 } 254 else 255 { 256 //UUUU draw PageFill and outline 257 drawFillAttributes(maPageFillAttributes, aRect, aRect); 258 } 259 260 if(bFrameDirection && !bTable) 261 { 262 //pImpl->nFrameDirection 263 Point aPos; 264 Font aFont(GetFont()); 265 const Size aSaveSize = aFont.GetSize(); 266 Size aDrawSize(0,aRect.GetHeight() / 6); 267 aFont.SetSize(aDrawSize); 268 SetFont(aFont); 269 String sText(String::CreateFromAscii("ABC")); 270 Point aMove(1,GetTextHeight()); 271 sal_Unicode cArrow = 0x2193; 272 long nAWidth = GetTextWidth(String(sText.GetChar(0))); 273 switch(nFrameDirection) 274 { 275 case FRMDIR_HORI_LEFT_TOP: 276 aPos = aRect.TopLeft(); 277 aPos.X() += PixelToLogic(Point(1,1)).X(); 278 aMove.Y() = 0; 279 cArrow = 0x2192; 280 break; 281 case FRMDIR_HORI_RIGHT_TOP: 282 aPos = aRect.TopRight(); 283 aPos.X() -= nAWidth; 284 aMove.Y() = 0; 285 aMove.X() *= -1; 286 cArrow = 0x2190; 287 break; 288 case FRMDIR_VERT_TOP_LEFT: 289 aPos = aRect.TopLeft(); 290 aPos.X() += PixelToLogic(Point(1,1)).X(); 291 aMove.X() = 0; 292 break; 293 case FRMDIR_VERT_TOP_RIGHT: 294 aPos = aRect.TopRight(); 295 aPos.X() -= nAWidth; 296 aMove.X() = 0; 297 break; 298 } 299 sText.Append(cArrow); 300 for(sal_uInt16 i = 0; i < sText.Len(); i++) 301 { 302 String sDraw(sText.GetChar(i)); 303 long nHDiff = 0; 304 long nCharWidth = GetTextWidth(sDraw); 305 sal_Bool bHorizontal = 0 == aMove.Y(); 306 if(!bHorizontal) 307 { 308 nHDiff = (nAWidth - nCharWidth) / 2; 309 aPos.X() += nHDiff; 310 } 311 DrawText(aPos,sDraw); 312 if(bHorizontal) 313 { 314 aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth; 315 } 316 else 317 { 318 aPos.X() -= nHDiff; 319 aPos.Y() += aMove.Y(); 320 } 321 } 322 aFont.SetSize(aSaveSize); 323 SetFont(aFont); 324 325 } 326 if(bTable) 327 { 328 // Tabelle malen, ggf. zentrieren 329 SetLineColor(Color(COL_LIGHTGRAY)); 330 331 long nW = aRect.GetWidth(),nH = aRect.GetHeight(); 332 long nTW = CELL_WIDTH * 3,nTH = CELL_HEIGHT * 3; 333 long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left(); 334 long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top(); 335 Rectangle aCellRect(Point(_nLeft,_nTop),Size(CELL_WIDTH,CELL_HEIGHT)); 336 337 for(sal_uInt16 i = 0; i < 3; ++i) 338 { 339 aCellRect.Left() = _nLeft; 340 aCellRect.Right() = _nLeft + CELL_WIDTH; 341 if(i > 0) 342 aCellRect.Move(0,CELL_HEIGHT); 343 344 for(sal_uInt16 j = 0; j < 3; ++j) 345 { 346 if(j > 0) 347 aCellRect.Move(CELL_WIDTH,0); 348 DrawRect(aCellRect); 349 } 350 } 351 } 352 } 353 354 //UUUU 355 void SvxPageWindow::drawFillAttributes( 356 const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes, 357 const Rectangle& rPaintRange, 358 const Rectangle& rDefineRange) 359 { 360 const basegfx::B2DRange aPaintRange( 361 rPaintRange.Left(), 362 rPaintRange.Top(), 363 rPaintRange.Right(), 364 rPaintRange.Bottom()); 365 366 if(!aPaintRange.isEmpty() && 367 !basegfx::fTools::equalZero(aPaintRange.getWidth()) && 368 !basegfx::fTools::equalZero(aPaintRange.getHeight())) 369 { 370 const basegfx::B2DRange aDefineRange( 371 rDefineRange.Left(), 372 rDefineRange.Top(), 373 rDefineRange.Right(), 374 rDefineRange.Bottom()); 375 376 // prepare primitive sequence 377 drawinglayer::primitive2d::Primitive2DSequence aSequence; 378 379 // create fill geometry if there is something to fill 380 if(rFillAttributes.get() && rFillAttributes->isUsed()) 381 { 382 aSequence = rFillAttributes->getPrimitive2DSequence( 383 aPaintRange, 384 aDefineRange); 385 } 386 387 // create line geometry if a LineColor is set at the target device 388 if(IsLineColor()) 389 { 390 const drawinglayer::primitive2d::Primitive2DReference xOutline( 391 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( 392 basegfx::tools::createPolygonFromRect(aPaintRange), 393 GetLineColor().getBColor())); 394 395 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 396 aSequence, 397 xOutline); 398 } 399 400 // draw that if we have something to draw 401 if(aSequence.getLength()) 402 { 403 const drawinglayer::geometry::ViewInformation2D aViewInformation2D( 404 basegfx::B2DHomMatrix(), 405 GetViewTransformation(), 406 aPaintRange, 407 0, 408 0.0, 409 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >()); 410 drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice( 411 *this, 412 aViewInformation2D); 413 414 if(pProcessor) 415 { 416 pProcessor->process(aSequence); 417 418 delete pProcessor; 419 } 420 } 421 } 422 } 423 424 // ----------------------------------------------------------------------- 425 426 void SvxPageWindow::SetBorder(const SvxBoxItem& rNew) 427 { 428 delete pBorder; 429 pBorder = new SvxBoxItem(rNew); 430 } 431 432 // ----------------------------------------------------------------------- 433 434 void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew) 435 { 436 delete pHdBorder; 437 pHdBorder = new SvxBoxItem(rNew); 438 } 439 // ----------------------------------------------------------------------- 440 441 void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew) 442 { 443 delete pFtBorder; 444 pFtBorder = new SvxBoxItem(rNew); 445 } 446 447 void SvxPageWindow::EnableFrameDirection(sal_Bool bEnable) 448 { 449 bFrameDirection = bEnable; 450 } 451 452 void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection) 453 { 454 nFrameDirection = nDirection; 455 } 456 457 void SvxPageWindow::ResetBackground() 458 { 459 bResetBackground = sal_True; 460 } 461 462 //eof 463