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
SvxPageWindow(Window * pParent,const ResId & rId)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
~SvxPageWindow()100 SvxPageWindow::~SvxPageWindow()
101 {
102 delete pHdBorder;
103 delete pFtBorder;
104 }
105
106 // -----------------------------------------------------------------------
107
Paint(const Rectangle &)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 // -----------------------------------------------------------------------
DrawPage(const Point & rOrg,const sal_Bool bSecond,const sal_Bool bEnabled)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
drawFillAttributes(const drawinglayer::attribute::SdrAllFillAttributesHelperPtr & rFillAttributes,const Rectangle & rPaintRange,const Rectangle & rDefineRange)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
SetBorder(const SvxBoxItem & rNew)426 void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
427 {
428 delete pBorder;
429 pBorder = new SvxBoxItem(rNew);
430 }
431
432 // -----------------------------------------------------------------------
433
SetHdBorder(const SvxBoxItem & rNew)434 void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
435 {
436 delete pHdBorder;
437 pHdBorder = new SvxBoxItem(rNew);
438 }
439 // -----------------------------------------------------------------------
440
SetFtBorder(const SvxBoxItem & rNew)441 void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
442 {
443 delete pFtBorder;
444 pFtBorder = new SvxBoxItem(rNew);
445 }
446
EnableFrameDirection(sal_Bool bEnable)447 void SvxPageWindow::EnableFrameDirection(sal_Bool bEnable)
448 {
449 bFrameDirection = bEnable;
450 }
451
SetFrameDirection(sal_Int32 nDirection)452 void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
453 {
454 nFrameDirection = nDirection;
455 }
456
ResetBackground()457 void SvxPageWindow::ResetBackground()
458 {
459 bResetBackground = sal_True;
460 }
461
462 //eof
463