Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/bitmap.hxx>
21 : #include <vcl/builderfactory.hxx>
22 : #include <vcl/settings.hxx>
23 : #include <tools/fract.hxx>
24 : #include <editeng/frmdiritem.hxx>
25 : #include <svx/pageitem.hxx>
26 : #include <svx/pagectrl.hxx>
27 : #include <editeng/boxitem.hxx>
28 : #include <algorithm>
29 : #include <basegfx/matrix/b2dhommatrix.hxx>
30 : #include <drawinglayer/geometry/viewinformation2d.hxx>
31 : #include <drawinglayer/processor2d/processor2dtools.hxx>
32 : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
33 : #include <basegfx/polygon/b2dpolygontools.hxx>
34 :
35 : #define CELL_WIDTH 1600L
36 : #define CELL_HEIGHT 800L
37 :
38 0 : SvxPageWindow::SvxPageWindow(vcl::Window* pParent)
39 : : Window(pParent),
40 : aWinSize(),
41 : aSize(),
42 :
43 : nTop(0),
44 : nBottom(0),
45 : nLeft(0),
46 : nRight(0),
47 :
48 : //UUUU
49 : pBorder(0),
50 : bResetBackground(false),
51 : bFrameDirection(false),
52 : nFrameDirection(0),
53 :
54 : nHdLeft(0),
55 : nHdRight(0),
56 : nHdDist(0),
57 : nHdHeight(0),
58 :
59 : pHdBorder(0),
60 : nFtLeft(0),
61 : nFtRight(0),
62 : nFtDist(0),
63 : nFtHeight(0),
64 :
65 : pFtBorder(0),
66 :
67 : maHeaderFillAttributes(),
68 : maFooterFillAttributes(),
69 : maPageFillAttributes(),
70 :
71 : bFooter(false),
72 : bHeader(false),
73 : bTable(false),
74 : bHorz(false),
75 : bVert(false),
76 : eUsage(SVX_PAGE_ALL),
77 :
78 : aLeftText(),
79 0 : aRightText()
80 : {
81 : // Count in Twips by default
82 0 : SetMapMode(MapMode(MAP_TWIP));
83 0 : aWinSize = GetOptimalSize();
84 0 : aWinSize.Height() -= 4;
85 0 : aWinSize.Width() -= 4;
86 :
87 0 : aWinSize = PixelToLogic(aWinSize);
88 0 : SetBackground();
89 0 : }
90 :
91 0 : SvxPageWindow::~SvxPageWindow()
92 : {
93 0 : disposeOnce();
94 0 : }
95 :
96 0 : void SvxPageWindow::dispose()
97 : {
98 0 : delete pHdBorder;
99 0 : delete pFtBorder;
100 0 : vcl::Window::dispose();
101 0 : }
102 :
103 0 : VCL_BUILDER_FACTORY(SvxPageWindow)
104 :
105 0 : void SvxPageWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
106 : {
107 0 : Fraction aXScale(aWinSize.Width(), std::max(long(aSize.Width() * 2 + aSize.Width() / 8), 1L));
108 0 : Fraction aYScale(aWinSize.Height(), std::max(aSize.Height(), 1L));
109 0 : MapMode aMapMode(rRenderContext.GetMapMode());
110 :
111 0 : if(aYScale < aXScale)
112 : {
113 0 : aMapMode.SetScaleX(aYScale);
114 0 : aMapMode.SetScaleY(aYScale);
115 : }
116 : else
117 : {
118 0 : aMapMode.SetScaleX(aXScale);
119 0 : aMapMode.SetScaleY(aXScale);
120 : }
121 0 : rRenderContext.SetMapMode(aMapMode);
122 0 : Size aSz(rRenderContext.PixelToLogic(GetSizePixel()));
123 0 : long nYPos = (aSz.Height() - aSize.Height()) / 2;
124 :
125 0 : if (eUsage == SVX_PAGE_ALL)
126 : {
127 : // all pages are equal -> draw one page
128 0 : if (aSize.Width() > aSize.Height())
129 : {
130 : // Draw Landscape page of the same size
131 0 : Fraction aX = aMapMode.GetScaleX();
132 0 : Fraction aY = aMapMode.GetScaleY();
133 0 : Fraction a2(1.5);
134 0 : aX *= a2;
135 0 : aY *= a2;
136 0 : aMapMode.SetScaleX(aX);
137 0 : aMapMode.SetScaleY(aY);
138 0 : rRenderContext.SetMapMode(aMapMode);
139 0 : aSz = rRenderContext.PixelToLogic(GetSizePixel());
140 0 : nYPos = (aSz.Height() - aSize.Height()) / 2;
141 0 : long nXPos = (aSz.Width() - aSize.Width()) / 2;
142 0 : DrawPage(rRenderContext, Point(nXPos,nYPos),true,true);
143 : }
144 : else
145 : // Portrait
146 0 : DrawPage(rRenderContext, Point((aSz.Width() - aSize.Width()) / 2,nYPos),true,true);
147 : }
148 : else
149 : {
150 : // Left and right page are different -> draw two pages if possible
151 0 : DrawPage(rRenderContext, Point(0, nYPos), false, (eUsage & SVX_PAGE_LEFT) != 0);
152 0 : DrawPage(rRenderContext, Point(aSize.Width() + aSize.Width() / 8, nYPos), true, (eUsage & SVX_PAGE_RIGHT) != 0);
153 0 : }
154 0 : }
155 :
156 0 : void SvxPageWindow::DrawPage(vcl::RenderContext& rRenderContext, const Point& rOrg, const bool bSecond, const bool bEnabled)
157 : {
158 0 : const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
159 0 : const Color& rFieldColor = rStyleSettings.GetFieldColor();
160 0 : const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
161 0 : const Color& rDisableColor = rStyleSettings.GetDisableColor();
162 0 : const Color& rDlgColor = rStyleSettings.GetDialogColor();
163 :
164 : // background
165 0 : if (!bSecond || bResetBackground)
166 : {
167 0 : rRenderContext.SetLineColor(Color(COL_TRANSPARENT));
168 0 : rRenderContext.SetFillColor(rDlgColor);
169 0 : Size winSize(rRenderContext.GetOutputSize());
170 0 : rRenderContext.DrawRect(Rectangle(Point(0,0), winSize));
171 :
172 0 : if (bResetBackground)
173 0 : bResetBackground = false;
174 : }
175 0 : rRenderContext.SetLineColor(rFieldTextColor);
176 :
177 : // Shadow
178 0 : Size aTempSize = aSize;
179 :
180 : // Page
181 0 : if (!bEnabled)
182 : {
183 0 : rRenderContext.SetFillColor(rDisableColor);
184 0 : rRenderContext.DrawRect(Rectangle(rOrg, aTempSize));
185 0 : return;
186 : }
187 0 : rRenderContext.SetFillColor(rFieldColor);
188 0 : rRenderContext.DrawRect(Rectangle(rOrg, aTempSize));
189 :
190 0 : long nL = nLeft;
191 0 : long nR = nRight;
192 :
193 0 : if (eUsage == SVX_PAGE_MIRROR && !bSecond)
194 : {
195 : // turn for mirrored
196 0 : nL = nRight;
197 0 : nR = nLeft;
198 : }
199 :
200 0 : Rectangle aRect;
201 :
202 0 : aRect.Left() = rOrg.X() + nL;
203 0 : aRect.Right() = rOrg.X() + aTempSize.Width() - nR;
204 0 : aRect.Top() = rOrg.Y() + nTop;
205 0 : aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom;
206 :
207 0 : Rectangle aHdRect(aRect);
208 0 : Rectangle aFtRect(aRect);
209 :
210 0 : if (bHeader || bFooter)
211 : {
212 : //UUUU Header and/or footer used
213 0 : const Color aLineColor(rRenderContext.GetLineColor());
214 :
215 : //UUUU draw PageFill first and on the whole page, no outline
216 0 : rRenderContext.SetLineColor();
217 0 : drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
218 0 : rRenderContext.SetLineColor(aLineColor);
219 :
220 0 : if (bHeader)
221 : {
222 : // show headers if possible
223 0 : aHdRect.Left() += nHdLeft;
224 0 : aHdRect.Right() -= nHdRight;
225 0 : aHdRect.Bottom() = aRect.Top() + nHdHeight;
226 0 : aRect.Top() += nHdHeight + nHdDist;
227 :
228 : // draw header over PageFill, plus outline
229 0 : drawFillAttributes(rRenderContext, maHeaderFillAttributes, aHdRect, aHdRect);
230 : }
231 :
232 0 : if (bFooter)
233 : {
234 : // show footer if possible
235 0 : aFtRect.Left() += nFtLeft;
236 0 : aFtRect.Right() -= nFtRight;
237 0 : aFtRect.Top() = aRect.Bottom() - nFtHeight;
238 0 : aRect.Bottom() -= nFtHeight + nFtDist;
239 :
240 : // draw footer over PageFill, plus outline
241 0 : drawFillAttributes(rRenderContext, maFooterFillAttributes, aFtRect, aFtRect);
242 : }
243 :
244 : // draw page's reduced outline, only outline
245 0 : drawFillAttributes(rRenderContext, drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
246 : }
247 : else
248 : {
249 : //UUUU draw PageFill and outline
250 0 : drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
251 : }
252 :
253 0 : if (bFrameDirection && !bTable)
254 : {
255 0 : Point aPos;
256 0 : vcl::Font aFont(rRenderContext.GetFont());
257 0 : const Size aSaveSize = aFont.GetSize();
258 0 : Size aDrawSize(0,aRect.GetHeight() / 6);
259 0 : aFont.SetSize(aDrawSize);
260 0 : rRenderContext.SetFont(aFont);
261 0 : OUString sText("ABC");
262 0 : Point aMove(1, rRenderContext.GetTextHeight());
263 0 : sal_Unicode cArrow = 0x2193;
264 0 : long nAWidth = rRenderContext.GetTextWidth(sText.copy(0,1));
265 0 : switch (nFrameDirection)
266 : {
267 : case FRMDIR_HORI_LEFT_TOP:
268 0 : aPos = aRect.TopLeft();
269 0 : aPos.X() += PixelToLogic(Point(1,1)).X();
270 0 : aMove.Y() = 0;
271 0 : cArrow = 0x2192;
272 0 : break;
273 : case FRMDIR_HORI_RIGHT_TOP:
274 0 : aPos = aRect.TopRight();
275 0 : aPos.X() -= nAWidth;
276 0 : aMove.Y() = 0;
277 0 : aMove.X() *= -1;
278 0 : cArrow = 0x2190;
279 0 : break;
280 : case FRMDIR_VERT_TOP_LEFT:
281 0 : aPos = aRect.TopLeft();
282 0 : aPos.X() += rRenderContext.PixelToLogic(Point(1,1)).X();
283 0 : aMove.X() = 0;
284 0 : break;
285 : case FRMDIR_VERT_TOP_RIGHT:
286 0 : aPos = aRect.TopRight();
287 0 : aPos.X() -= nAWidth;
288 0 : aMove.X() = 0;
289 0 : break;
290 : }
291 0 : sText += OUString(cArrow);
292 0 : for (sal_Int32 i = 0; i < sText.getLength(); i++)
293 : {
294 0 : OUString sDraw(sText.copy(i,1));
295 0 : long nHDiff = 0;
296 0 : long nCharWidth = GetTextWidth(sDraw);
297 0 : bool bHorizontal = 0 == aMove.Y();
298 0 : if (!bHorizontal)
299 : {
300 0 : nHDiff = (nAWidth - nCharWidth) / 2;
301 0 : aPos.X() += nHDiff;
302 : }
303 0 : rRenderContext.DrawText(aPos,sDraw);
304 0 : if (bHorizontal)
305 : {
306 0 : aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth;
307 : }
308 : else
309 : {
310 0 : aPos.X() -= nHDiff;
311 0 : aPos.Y() += aMove.Y();
312 : }
313 0 : }
314 0 : aFont.SetSize(aSaveSize);
315 0 : rRenderContext.SetFont(aFont);
316 :
317 : }
318 0 : if (bTable)
319 : {
320 : // Paint Table, if necessary center it
321 0 : rRenderContext.SetLineColor(Color(COL_LIGHTGRAY));
322 :
323 0 : long nW = aRect.GetWidth();
324 0 : long nH = aRect.GetHeight();
325 0 : long nTW = CELL_WIDTH * 3;
326 0 : long nTH = CELL_HEIGHT * 3;
327 0 : long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
328 0 : long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
329 0 : Rectangle aCellRect(Point(_nLeft, _nTop),Size(CELL_WIDTH, CELL_HEIGHT));
330 :
331 0 : for (sal_uInt16 i = 0; i < 3; ++i)
332 : {
333 0 : aCellRect.Left() = _nLeft;
334 0 : aCellRect.Right() = _nLeft + CELL_WIDTH;
335 0 : if(i > 0)
336 0 : aCellRect.Move(0,CELL_HEIGHT);
337 :
338 0 : for (sal_uInt16 j = 0; j < 3; ++j)
339 : {
340 0 : if (j > 0)
341 0 : aCellRect.Move(CELL_WIDTH,0);
342 0 : rRenderContext.DrawRect(aCellRect);
343 : }
344 : }
345 : }
346 : }
347 :
348 : //UUUU
349 0 : void SvxPageWindow::drawFillAttributes(vcl::RenderContext& rRenderContext,
350 : const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
351 : const Rectangle& rPaintRange,
352 : const Rectangle& rDefineRange)
353 : {
354 : const basegfx::B2DRange aPaintRange(
355 0 : rPaintRange.Left(),
356 0 : rPaintRange.Top(),
357 0 : rPaintRange.Right(),
358 0 : rPaintRange.Bottom());
359 :
360 0 : if(!aPaintRange.isEmpty() &&
361 0 : !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
362 0 : !basegfx::fTools::equalZero(aPaintRange.getHeight()))
363 : {
364 : const basegfx::B2DRange aDefineRange(
365 0 : rDefineRange.Left(),
366 0 : rDefineRange.Top(),
367 0 : rDefineRange.Right(),
368 0 : rDefineRange.Bottom());
369 :
370 : // prepare primitive sequence
371 0 : drawinglayer::primitive2d::Primitive2DSequence aSequence;
372 :
373 : // create fill geometry if there is something to fill
374 0 : if (rFillAttributes.get() && rFillAttributes->isUsed())
375 : {
376 0 : aSequence = rFillAttributes->getPrimitive2DSequence(aPaintRange, aDefineRange);
377 : }
378 :
379 : // create line geometry if a LineColor is set at the target device
380 0 : if (rRenderContext.IsLineColor())
381 : {
382 : const drawinglayer::primitive2d::Primitive2DReference xOutline(
383 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
384 0 : basegfx::tools::createPolygonFromRect(aPaintRange), GetLineColor().getBColor()));
385 :
386 0 : drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aSequence, xOutline);
387 : }
388 :
389 : // draw that if we have something to draw
390 0 : if (aSequence.getLength())
391 : {
392 : const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
393 : basegfx::B2DHomMatrix(), GetViewTransformation(), aPaintRange, 0,
394 0 : 0.0, css::uno::Sequence<css::beans::PropertyValue >());
395 :
396 0 : std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor;
397 0 : pProcessor.reset(drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext, aViewInformation2D));
398 :
399 0 : if (pProcessor)
400 : {
401 0 : pProcessor->process(aSequence);
402 0 : }
403 0 : }
404 : }
405 0 : }
406 :
407 :
408 :
409 0 : void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
410 : {
411 0 : delete pBorder;
412 0 : pBorder = new SvxBoxItem(rNew);
413 0 : }
414 :
415 :
416 :
417 0 : void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
418 : {
419 0 : delete pHdBorder;
420 0 : pHdBorder = new SvxBoxItem(rNew);
421 0 : }
422 :
423 :
424 0 : void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
425 : {
426 0 : delete pFtBorder;
427 0 : pFtBorder = new SvxBoxItem(rNew);
428 0 : }
429 :
430 0 : void SvxPageWindow::EnableFrameDirection(bool bEnable)
431 : {
432 0 : bFrameDirection = bEnable;
433 0 : }
434 :
435 0 : void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
436 : {
437 0 : nFrameDirection = nDirection;
438 0 : }
439 :
440 0 : void SvxPageWindow::ResetBackground()
441 : {
442 0 : bResetBackground = true;
443 0 : }
444 :
445 0 : Size SvxPageWindow::GetOptimalSize() const
446 : {
447 0 : return LogicToPixel(Size(75, 46), MapMode(MAP_APPFONT));
448 390 : }
449 :
450 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|