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 
125 void 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 
141  if (bResetBackground)
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()) ||
327  basegfx::fTools::equalZero(aPaintRange.getHeight()))
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 
355  const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
356  basegfx::B2DHomMatrix(), rRenderContext.GetViewTransformation(), aPaintRange, nullptr, 0.0);
357 
358  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
359  drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext, aViewInformation2D));
360  pProcessor->process(aSequence);
361 }
362 
364 {
365  bFrameDirection = bEnable;
366 }
367 
369 {
370  nFrameDirection = nDirection;
371 }
372 
374 {
375  bResetBackground = true;
376 }
377 
379 {
380  CustomWidgetController::SetDrawingArea(pDrawingArea);
381 
382  OutputDevice& rRefDevice = pDrawingArea->get_ref_device();
383  // Count in Twips by default
384  rRefDevice.Push(vcl::PushFlags::MAPMODE);
385  rRefDevice.SetMapMode(MapMode(MapUnit::MapTwip));
386  aWinSize = rRefDevice.LogicToPixel(Size(75, 46), MapMode(MapUnit::MapAppFont));
387  pDrawingArea->set_size_request(aWinSize.Width(), aWinSize.Height());
388 
389  aWinSize.AdjustHeight( -4 );
390  aWinSize.AdjustWidth( -4 );
391 
392  aWinSize = rRefDevice.PixelToLogic(aWinSize);
393  rRefDevice.Pop();
394 }
395 
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: pagectrl.cxx:68
tools::Long nRight
Definition: pagectrl.hxx:38
const Color & GetDialogColor() const
tools::Long nHdLeft
Definition: pagectrl.hxx:44
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 AdjustRight(tools::Long nHorzMoveDelta)
bool equalZero(const T &rfVal)
constexpr tools::Long Left() const
tools::Long nHdHeight
Definition: pagectrl.hxx:47
long Long
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
const StyleSettings & GetStyleSettings() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
#define CELL_HEIGHT
Definition: pagectrl.cxx:37
SvxFrameDirection nFrameDirection
Definition: pagectrl.hxx:42
const MapMode & GetMapMode() const
SvxFrameDirection
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
tools::Long nLeft
Definition: pagectrl.hxx:37
#define CELL_WIDTH
Definition: pagectrl.cxx:36
void SetMapMode()
const Color & GetFieldTextColor() const
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
Size const & GetOutputSizePixel() const
constexpr tools::Long Width() const
sal_uInt16 sal_Unicode
const vcl::Font & GetFont() const
tools::Long nFtHeight
Definition: pagectrl.hxx:52
std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr
constexpr tools::Long GetWidth() const
virtual OutputDevice & get_ref_device()=0
void ResetBackground()
Definition: pagectrl.cxx:373
void SetFrameDirection(SvxFrameDirection nDirection)
Definition: pagectrl.cxx:368
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void DrawRect(const tools::Rectangle &rRect)
constexpr void SetLeft(tools::Long v)
void SetLineColor()
const Color & GetDisableColor() const
tools::Long nFtRight
Definition: pagectrl.hxx:50
int i
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
tools::Long nFtLeft
Definition: pagectrl.hxx:49
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
Size GetOutputSize() const
void SetFillColor()
const Color & GetFieldColor() const
tools::Long nBottom
Definition: pagectrl.hxx:36
const Color & GetLineColor() const
constexpr tools::Long Top() const
tools::Long nHdDist
Definition: pagectrl.hxx:46
constexpr void SetRight(tools::Long v)
const AllSettings & GetSettings() const
constexpr void SetBottom(tools::Long v)
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: pagectrl.cxx:378
constexpr void SetTop(tools::Long v)
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maFooterFillAttributes
Definition: pagectrl.hxx:55
tools::Long nTop
Definition: pagectrl.hxx:35
SvxPageUsage
Definition: pageitem.hxx:32
constexpr Point TopLeft() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long nHdRight
Definition: pagectrl.hxx:45
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
constexpr tools::Long Bottom() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
tools::Long nFtDist
Definition: pagectrl.hxx:51
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maPageFillAttributes
Definition: pagectrl.hxx:56
constexpr tools::Long Height() const
void SetFont(const vcl::Font &rNewFont)
drawinglayer::attribute::SdrAllFillAttributesHelperPtr maHeaderFillAttributes
Definition: pagectrl.hxx:54
tools::Long GetTextHeight() const
constexpr Point TopRight() const
virtual void DrawPage(vcl::RenderContext &rRenderContext, const Point &rPoint, const bool bSecond, const bool bEnabled)
Definition: pagectrl.cxx:125
tools::Long AdjustWidth(tools::Long n)
virtual ~SvxPageWindow() override
Definition: pagectrl.cxx:64
tools::Long AdjustHeight(tools::Long n)
basegfx::BColor getBColor() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
SvxPageUsage eUsage
Definition: pagectrl.hxx:64
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
bool bFrameDirection
Definition: pagectrl.hxx:41
void EnableFrameDirection(bool bEnable)
Definition: pagectrl.cxx:363
virtual void set_size_request(int nWidth, int nHeight)=0
basegfx::B2DHomMatrix GetViewTransformation() 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)
bool bResetBackground
Definition: pagectrl.hxx:40
bool m_bDetectedRangeSegmentation false
constexpr tools::Long GetHeight() const