LibreOffice Module svx (master) 1
pagectrl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <editeng/frmdir.hxx>
22#include <vcl/canvastools.hxx>
23#include <vcl/outdev.hxx>
24#include <vcl/settings.hxx>
25#include <tools/fract.hxx>
26#include <svx/pageitem.hxx>
27#include <svx/pagectrl.hxx>
28#include <algorithm>
35
36#define CELL_WIDTH 1600L
37#define CELL_HEIGHT 800L
38
40 nTop(0),
41 nBottom(0),
42 nLeft(0),
43 nRight(0),
44 bResetBackground(false),
45 bFrameDirection(false),
46 nFrameDirection(SvxFrameDirection::Horizontal_LR_TB),
47 nHdLeft(0),
48 nHdRight(0),
49 nHdDist(0),
50 nHdHeight(0),
51 nFtLeft(0),
52 nFtRight(0),
53 nFtDist(0),
54 nFtHeight(0),
55 bFooter(false),
56 bHeader(false),
57 bTable(false),
58 bHorz(false),
59 bVert(false),
60 eUsage(SvxPageUsage::All)
61{
62}
63
65{
66}
67
69{
70 rRenderContext.Push(vcl::PushFlags::MAPMODE);
71 rRenderContext.SetMapMode(MapMode(MapUnit::MapTwip));
72
73 Fraction aXScale(aWinSize.Width(), std::max(aSize.Width() * 2 + aSize.Width() / 8, tools::Long(1)));
74 Fraction aYScale(aWinSize.Height(), std::max(aSize.Height(), tools::Long(1)));
75 MapMode aMapMode(rRenderContext.GetMapMode());
76
77 if(aYScale < aXScale)
78 {
79 aMapMode.SetScaleX(aYScale);
80 aMapMode.SetScaleY(aYScale);
81 }
82 else
83 {
84 aMapMode.SetScaleX(aXScale);
85 aMapMode.SetScaleY(aXScale);
86 }
87 rRenderContext.SetMapMode(aMapMode);
88 Size aSz(rRenderContext.PixelToLogic(GetOutputSizePixel()));
89 tools::Long nYPos = (aSz.Height() - aSize.Height()) / 2;
90
92 {
93 // all pages are equal -> draw one page
94 if (aSize.Width() > aSize.Height())
95 {
96 // Draw Landscape page of the same size
97 Fraction aX = aMapMode.GetScaleX();
98 Fraction aY = aMapMode.GetScaleY();
99 Fraction a2(1.5);
100 aX *= a2;
101 aY *= a2;
102 aMapMode.SetScaleX(aX);
103 aMapMode.SetScaleY(aY);
104 rRenderContext.SetMapMode(aMapMode);
105 aSz = rRenderContext.PixelToLogic(GetOutputSizePixel());
106 nYPos = (aSz.Height() - aSize.Height()) / 2;
107 tools::Long nXPos = (aSz.Width() - aSize.Width()) / 2;
108 DrawPage(rRenderContext, Point(nXPos,nYPos),true,true);
109 }
110 else
111 // Portrait
112 DrawPage(rRenderContext, Point((aSz.Width() - aSize.Width()) / 2,nYPos),true,true);
113 }
114 else
115 {
116 // Left and right page are different -> draw two pages if possible
117 DrawPage(rRenderContext, Point(0, nYPos), false,
119 DrawPage(rRenderContext, Point(aSize.Width() + aSize.Width() / 8, nYPos), true,
121 }
122 rRenderContext.Pop();
123}
124
125void SvxPageWindow::DrawPage(vcl::RenderContext& rRenderContext, const Point& rOrg, const bool bSecond, const bool bEnabled)
126{
127 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
128 const Color& rFieldColor = rStyleSettings.GetFieldColor();
129 const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
130 const Color& rDisableColor = rStyleSettings.GetDisableColor();
131 const Color& rDlgColor = rStyleSettings.GetDialogColor();
132
133 // background
134 if (!bSecond || bResetBackground)
135 {
136 rRenderContext.SetLineColor(COL_TRANSPARENT);
137 rRenderContext.SetFillColor(rDlgColor);
138 Size winSize(rRenderContext.GetOutputSize());
139 rRenderContext.DrawRect(tools::Rectangle(Point(0,0), winSize));
140
142 bResetBackground = false;
143 }
144 rRenderContext.SetLineColor(rFieldTextColor);
145
146 // Shadow
147 Size aTempSize = aSize;
148
149 // Page
150 if (!bEnabled)
151 {
152 rRenderContext.SetFillColor(rDisableColor);
153 rRenderContext.DrawRect(tools::Rectangle(rOrg, aTempSize));
154 return;
155 }
156 rRenderContext.SetFillColor(rFieldColor);
157 rRenderContext.DrawRect(tools::Rectangle(rOrg, aTempSize));
158
159 tools::Long nL = nLeft;
160 tools::Long nR = nRight;
161
162 if (eUsage == SvxPageUsage::Mirror && !bSecond)
163 {
164 // turn for mirrored
165 nL = nRight;
166 nR = nLeft;
167 }
168
169 tools::Rectangle aRect;
170
171 aRect.SetLeft( rOrg.X() + nL );
172 aRect.SetRight( rOrg.X() + aTempSize.Width() - nR );
173 aRect.SetTop( rOrg.Y() + nTop );
174 aRect.SetBottom( rOrg.Y() + aTempSize.Height() - nBottom );
175
176 tools::Rectangle aHdRect(aRect);
177 tools::Rectangle aFtRect(aRect);
178
179 if (bHeader || bFooter)
180 {
181 // Header and/or footer used
182 const Color aLineColor(rRenderContext.GetLineColor());
183
184 // draw PageFill first and on the whole page, no outline
185 rRenderContext.SetLineColor();
186 drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
187 rRenderContext.SetLineColor(aLineColor);
188
189 if (bHeader)
190 {
191 // show headers if possible
192 aHdRect.AdjustLeft(nHdLeft );
193 aHdRect.AdjustRight( -nHdRight );
194 aHdRect.SetBottom( aRect.Top() + nHdHeight );
195 aRect.AdjustTop(nHdHeight + nHdDist );
196
197 // draw header over PageFill, plus outline
198 drawFillAttributes(rRenderContext, maHeaderFillAttributes, aHdRect, aHdRect);
199 }
200
201 if (bFooter)
202 {
203 // show footer if possible
204 aFtRect.AdjustLeft(nFtLeft );
205 aFtRect.AdjustRight( -nFtRight );
206 aFtRect.SetTop( aRect.Bottom() - nFtHeight );
207 aRect.AdjustBottom( -(nFtHeight + nFtDist) );
208
209 // draw footer over PageFill, plus outline
210 drawFillAttributes(rRenderContext, maFooterFillAttributes, aFtRect, aFtRect);
211 }
212
213 // draw page's reduced outline, only outline
215 }
216 else
217 {
218 // draw PageFill and outline
219 drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
220 }
221
222 if (bFrameDirection && !bTable)
223 {
224 Point aPos;
225 vcl::Font aFont(rRenderContext.GetFont());
226 const Size aSaveSize = aFont.GetFontSize();
227 Size aDrawSize(0,aRect.GetHeight() / 6);
228 aFont.SetFontSize(aDrawSize);
229 rRenderContext.SetFont(aFont);
230 OUString sText("ABC");
231 Point aMove(1, rRenderContext.GetTextHeight());
232 sal_Unicode cArrow = 0x2193;
233 tools::Long nAWidth = rRenderContext.GetTextWidth(sText.copy(0,1));
234 switch (nFrameDirection)
235 {
236 case SvxFrameDirection::Horizontal_LR_TB:
237 aPos = aRect.TopLeft();
238 aPos.AdjustX(rRenderContext.PixelToLogic(Point(1,1)).X() );
239 aMove.setY( 0 );
240 cArrow = 0x2192;
241 break;
242 case SvxFrameDirection::Horizontal_RL_TB:
243 aPos = aRect.TopRight();
244 aPos.AdjustX( -nAWidth );
245 aMove.setY( 0 );
246 aMove.setX( aMove.X() * -1 );
247 cArrow = 0x2190;
248 break;
249 case SvxFrameDirection::Vertical_LR_TB:
250 aPos = aRect.TopLeft();
251 aPos.AdjustX(rRenderContext.PixelToLogic(Point(1,1)).X() );
252 aMove.setX( 0 );
253 break;
254 case SvxFrameDirection::Vertical_RL_TB:
255 aPos = aRect.TopRight();
256 aPos.AdjustX( -nAWidth );
257 aMove.setX( 0 );
258 break;
259 default: break;
260 }
261 sText += OUStringChar(cArrow);
262 for (sal_Int32 i = 0; i < sText.getLength(); i++)
263 {
264 OUString sDraw(sText.copy(i,1));
265 tools::Long nHDiff = 0;
266 tools::Long nCharWidth = rRenderContext.GetTextWidth(sDraw);
267 bool bHorizontal = 0 == aMove.Y();
268 if (!bHorizontal)
269 {
270 nHDiff = (nAWidth - nCharWidth) / 2;
271 aPos.AdjustX(nHDiff );
272 }
273 rRenderContext.DrawText(aPos,sDraw);
274 if (bHorizontal)
275 {
276 aPos.AdjustX(aMove.X() < 0 ? -nCharWidth : nCharWidth );
277 }
278 else
279 {
280 aPos.AdjustX( -nHDiff );
281 aPos.AdjustY(aMove.Y() );
282 }
283 }
284 aFont.SetFontSize(aSaveSize);
285 rRenderContext.SetFont(aFont);
286
287 }
288 if (!bTable)
289 return;
290
291 // Paint Table, if necessary center it
292 rRenderContext.SetLineColor(COL_LIGHTGRAY);
293
294 tools::Long nW = aRect.GetWidth();
295 tools::Long nH = aRect.GetHeight();
296 tools::Long const nTW = CELL_WIDTH * 3;
297 tools::Long const nTH = CELL_HEIGHT * 3;
298 tools::Long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
299 tools::Long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
300 tools::Rectangle aCellRect(Point(_nLeft, _nTop),Size(CELL_WIDTH, CELL_HEIGHT));
301
302 for (sal_uInt16 i = 0; i < 3; ++i)
303 {
304 aCellRect.SetLeft( _nLeft );
305 aCellRect.SetRight( _nLeft + CELL_WIDTH );
306 if(i > 0)
307 aCellRect.Move(0,CELL_HEIGHT);
308
309 for (sal_uInt16 j = 0; j < 3; ++j)
310 {
311 if (j > 0)
312 aCellRect.Move(CELL_WIDTH,0);
313 rRenderContext.DrawRect(aCellRect);
314 }
315 }
316}
317
320 const tools::Rectangle& rPaintRange,
321 const tools::Rectangle& rDefineRange)
322{
323 const basegfx::B2DRange aPaintRange = vcl::unotools::b2DRectangleFromRectangle(rPaintRange);
324
325 if(aPaintRange.isEmpty() ||
326 basegfx::fTools::equalZero(aPaintRange.getWidth()) ||
328 return;
329
330 const basegfx::B2DRange aDefineRange = vcl::unotools::b2DRectangleFromRectangle(rDefineRange);
331
332 // prepare primitive sequence
334
335 // create fill geometry if there is something to fill
336 if (rFillAttributes && rFillAttributes->isUsed())
337 {
338 aSequence = rFillAttributes->getPrimitive2DSequence(aPaintRange, aDefineRange);
339 }
340
341 // create line geometry if a LineColor is set at the target device
342 if (rRenderContext.IsLineColor())
343 {
346 basegfx::utils::createPolygonFromRect(aPaintRange), rRenderContext.GetLineColor().getBColor()));
347
348 aSequence.push_back(xOutline);
349 }
350
351 // draw that if we have something to draw
352 if (aSequence.empty())
353 return;
354
356 aViewInformation2D.setViewTransformation(rRenderContext.GetViewTransformation());
357 aViewInformation2D.setViewport(aPaintRange);
358
359 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
360 drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext, aViewInformation2D));
361 pProcessor->process(aSequence);
362}
363
365{
366 bFrameDirection = bEnable;
367}
368
370{
371 nFrameDirection = nDirection;
372}
373
375{
376 bResetBackground = true;
377}
378
380{
381 CustomWidgetController::SetDrawingArea(pDrawingArea);
382
383 OutputDevice& rRefDevice = pDrawingArea->get_ref_device();
384 // Count in Twips by default
385 rRefDevice.Push(vcl::PushFlags::MAPMODE);
386 rRefDevice.SetMapMode(MapMode(MapUnit::MapTwip));
387 aWinSize = rRefDevice.LogicToPixel(Size(75, 46), MapMode(MapUnit::MapAppFont));
388 pDrawingArea->set_size_request(aWinSize.Width(), aWinSize.Height());
389
391 aWinSize.AdjustWidth( -4 );
392
393 aWinSize = rRefDevice.PixelToLogic(aWinSize);
394 rRefDevice.Pop();
395}
396
397/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const StyleSettings & GetStyleSettings() const
basegfx::BColor getBColor() const
void SetScaleY(const Fraction &rScaleY)
const Fraction & GetScaleX() const
const Fraction & GetScaleY() const
void SetScaleX(const Fraction &rScaleX)
Size GetOutputSize() const
basegfx::B2DHomMatrix GetViewTransformation() const
const vcl::Font & GetFont() const
void SetFont(const vcl::Font &rNewFont)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void DrawRect(const tools::Rectangle &rRect)
void SetLineColor()
void SetMapMode()
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
bool IsLineColor() const
void SetFillColor()
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
const Color & GetLineColor() const
const MapMode & GetMapMode() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
tools::Long GetTextHeight() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
const AllSettings & GetSettings() const
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
tools::Long AdjustWidth(tools::Long n)
constexpr tools::Long Width() const
const Color & GetFieldTextColor() const
const Color & GetFieldColor() const
const Color & GetDialogColor() const
const Color & GetDisableColor() const
tools::Long nHdLeft
Definition: pagectrl.hxx:44
tools::Long nFtRight
Definition: pagectrl.hxx:50
void SetFrameDirection(SvxFrameDirection nDirection)
Definition: pagectrl.cxx:369
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maPageFillAttributes
Definition: pagectrl.hxx:56
SvxPageUsage eUsage
Definition: pagectrl.hxx:64
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maFooterFillAttributes
Definition: pagectrl.hxx:55
void ResetBackground()
Definition: pagectrl.cxx:374
SvxFrameDirection nFrameDirection
Definition: pagectrl.hxx:42
tools::Long nHdHeight
Definition: pagectrl.hxx:47
tools::Long nFtDist
Definition: pagectrl.hxx:51
static void drawFillAttributes(vcl::RenderContext &rRenderContext, const drawinglayer::attribute::SdrAllFillAttributesHelperPtr &rFillAttributes, const tools::Rectangle &rPaintRange, const tools::Rectangle &rDefineRange)
Definition: pagectrl.cxx:318
tools::Long nRight
Definition: pagectrl.hxx:38
tools::Long nFtHeight
Definition: pagectrl.hxx:52
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: pagectrl.cxx:379
virtual ~SvxPageWindow() override
Definition: pagectrl.cxx:64
tools::Long nHdDist
Definition: pagectrl.hxx:46
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: pagectrl.cxx:68
tools::Long nLeft
Definition: pagectrl.hxx:37
tools::Long nBottom
Definition: pagectrl.hxx:36
void EnableFrameDirection(bool bEnable)
Definition: pagectrl.cxx:364
tools::Long nTop
Definition: pagectrl.hxx:35
tools::Long nHdRight
Definition: pagectrl.hxx:45
bool bFrameDirection
Definition: pagectrl.hxx:41
bool bResetBackground
Definition: pagectrl.hxx:40
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maHeaderFillAttributes
Definition: pagectrl.hxx:54
virtual void DrawPage(vcl::RenderContext &rRenderContext, const Point &rPoint, const bool bSecond, const bool bEnabled)
Definition: pagectrl.cxx:125
tools::Long nFtLeft
Definition: pagectrl.hxx:49
TYPE getWidth() const
bool isEmpty() const
TYPE getHeight() const
void setViewport(const basegfx::B2DRange &rNew)
void setViewTransformation(const basegfx::B2DHomMatrix &rNew)
constexpr tools::Long GetWidth() const
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr void SetRight(tools::Long v)
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr void SetBottom(tools::Long v)
constexpr Point TopRight() const
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
void SetFontSize(const Size &)
const Size & GetFontSize() const
Size const & GetOutputSizePixel() const
virtual OutputDevice & get_ref_device()=0
virtual void set_size_request(int nWidth, int nHeight)=0
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
SvxFrameDirection
bool equalZero(const T &rfVal)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
int i
long Long
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
#define CELL_HEIGHT
Definition: pagectrl.cxx:37
#define CELL_WIDTH
Definition: pagectrl.cxx:36
SvxPageUsage
Definition: pageitem.hxx:33
sal_uInt16 sal_Unicode