blob: 7616b4b0e50b93961632debd5870754cae8d81d0 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <vcl/bitmap.hxx>
#include <editeng/frmdiritem.hxx>
#include <svx/pageitem.hxx>
#include <svx/pagectrl.hxx>
#include <editeng/boxitem.hxx>
#include <algorithm>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <drawinglayer/processor2d/processor2dtools.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
// STATIC DATA -----------------------------------------------------------
#define CELL_WIDTH 1600L
#define CELL_HEIGHT 800L
// class SvxPageWindow ---------------------------------------------------
SvxPageWindow::SvxPageWindow(Window* pParent,const ResId& rId)
: Window(pParent,rId),
aWinSize(),
aSize(),
nTop(0),
nBottom(0),
nLeft(0),
nRight(0),
//UUUU
pBorder(0),
bResetBackground(sal_False),
bFrameDirection(sal_False),
nFrameDirection(0),
nHdLeft(0),
nHdRight(0),
nHdDist(0),
nHdHeight(0),
pHdBorder(0),
nFtLeft(0),
nFtRight(0),
nFtDist(0),
nFtHeight(0),
pFtBorder(0),
maHeaderFillAttributes(),
maFooterFillAttributes(),
maPageFillAttributes(),
bFooter(sal_False),
bHeader(sal_False),
bTable(sal_False),
bHorz(sal_False),
bVert(sal_False),
eUsage(SVX_PAGE_ALL),
aLeftText(),
aRightText()
{
// defaultmaessing in Twips rechnen
SetMapMode(MapMode(MAP_TWIP));
aWinSize = GetOutputSizePixel();
aWinSize.Height() -= 4;
aWinSize.Width() -= 4;
aWinSize = PixelToLogic(aWinSize);
SetBackground();
}
// -----------------------------------------------------------------------
SvxPageWindow::~SvxPageWindow()
{
delete pHdBorder;
delete pFtBorder;
}
// -----------------------------------------------------------------------
void __EXPORT SvxPageWindow::Paint(const Rectangle&)
{
Fraction aXScale(aWinSize.Width(),std::max((long)(aSize.Width() * 2 + aSize.Width() / 8),1L));
Fraction aYScale(aWinSize.Height(),std::max(aSize.Height(),1L));
MapMode aMapMode(GetMapMode());
if(aYScale < aXScale)
{
aMapMode.SetScaleX(aYScale);
aMapMode.SetScaleY(aYScale);
}
else
{
aMapMode.SetScaleX(aXScale);
aMapMode.SetScaleY(aXScale);
}
SetMapMode(aMapMode);
Size aSz(PixelToLogic(GetSizePixel()));
long nYPos = (aSz.Height() - aSize.Height()) / 2;
if(eUsage == SVX_PAGE_ALL)
{
// alle Seiten gleich -> eine Seite malen
if(aSize.Width() > aSize.Height())
{
// Querformat in gleicher Gr"osse zeichnen
Fraction aX = aMapMode.GetScaleX();
Fraction aY = aMapMode.GetScaleY();
Fraction a2(1.5);
aX *= a2;
aY *= a2;
aMapMode.SetScaleX(aX);
aMapMode.SetScaleY(aY);
SetMapMode(aMapMode);
aSz = PixelToLogic(GetSizePixel());
nYPos = (aSz.Height() - aSize.Height()) / 2;
long nXPos = (aSz.Width() - aSize.Width()) / 2;
DrawPage(Point(nXPos,nYPos),sal_True,sal_True);
}
else
// Hochformat
DrawPage(Point((aSz.Width() - aSize.Width()) / 2,nYPos),sal_True,sal_True);
}
else
{
// Linke und rechte Seite unterschiedlich -> ggf. zwei Seiten malen
DrawPage(Point(0,nYPos),sal_False,(sal_Bool)(eUsage & SVX_PAGE_LEFT));
DrawPage(Point(aSize.Width() + aSize.Width() / 8,nYPos),sal_True,
(sal_Bool)(eUsage & SVX_PAGE_RIGHT));
}
}
// -----------------------------------------------------------------------
void SvxPageWindow::DrawPage(const Point& rOrg,const sal_Bool bSecond,const sal_Bool bEnabled)
{
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
const Color& rFieldColor = rStyleSettings.GetFieldColor();
const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
const Color& rDisableColor = rStyleSettings.GetDisableColor();
const Color& rDlgColor = rStyleSettings.GetDialogColor();
// background
if(!bSecond || bResetBackground)
{
SetLineColor(Color(COL_TRANSPARENT));
SetFillColor(rDlgColor);
Size winSize(GetOutputSize());
DrawRect(Rectangle(Point(0,0),winSize));
if(bResetBackground)
bResetBackground = sal_False;
}
SetLineColor(rFieldTextColor);
// Schatten
Size aTempSize = aSize;
// Seite
if(!bEnabled)
{
SetFillColor(rDisableColor);
DrawRect(Rectangle(rOrg,aTempSize));
return;
}
SetFillColor(rFieldColor);
DrawRect(Rectangle(rOrg,aTempSize));
// Border Top Bottom Left Right
Point aBegin(rOrg);
Point aEnd(rOrg);
long nL = nLeft;
long nR = nRight;
if(eUsage == SVX_PAGE_MIRROR && !bSecond)
{
// f"ur gespiegelt drehen
nL = nRight;
nR = nLeft;
}
Rectangle aRect;
aRect.Left() = rOrg.X() + nL;
aRect.Right() = rOrg.X() + aTempSize.Width() - nR;
aRect.Top() = rOrg.Y() + nTop;
aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom;
Rectangle aHdRect(aRect);
Rectangle aFtRect(aRect);
if(bHeader || bFooter)
{
//UUUU Header and/or footer used
const Color aLineColor(GetLineColor());
//UUUU draw PageFill first and on the whole page, no outline
SetLineColor();
drawFillAttributes(maPageFillAttributes, aRect, aRect);
SetLineColor(aLineColor);
if(bHeader)
{
// ggf. Header anzeigen
aHdRect.Left() += nHdLeft;
aHdRect.Right() -= nHdRight;
aHdRect.Bottom() = aRect.Top() + nHdHeight;
aRect.Top() += nHdHeight + nHdDist;
// draw header over PageFill, plus outline
drawFillAttributes(maHeaderFillAttributes, aHdRect, aHdRect);
}
if(bFooter)
{
// ggf. Footer anzeigen
aFtRect.Left() += nFtLeft;
aFtRect.Right() -= nFtRight;
aFtRect.Top() = aRect.Bottom() - nFtHeight;
aRect.Bottom() -= nFtHeight + nFtDist;
// draw footer over PageFill, plus outline
drawFillAttributes(maFooterFillAttributes, aFtRect, aFtRect);
}
// draw page's reduced outline, only outline
drawFillAttributes(drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
}
else
{
//UUUU draw PageFill and outline
drawFillAttributes(maPageFillAttributes, aRect, aRect);
}
if(bFrameDirection && !bTable)
{
//pImpl->nFrameDirection
Point aPos;
Font aFont(GetFont());
const Size aSaveSize = aFont.GetSize();
Size aDrawSize(0,aRect.GetHeight() / 6);
aFont.SetSize(aDrawSize);
SetFont(aFont);
String sText(String::CreateFromAscii("ABC"));
Point aMove(1,GetTextHeight());
sal_Unicode cArrow = 0x2193;
long nAWidth = GetTextWidth(String(sText.GetChar(0)));
switch(nFrameDirection)
{
case FRMDIR_HORI_LEFT_TOP:
aPos = aRect.TopLeft();
aPos.X() += PixelToLogic(Point(1,1)).X();
aMove.Y() = 0;
cArrow = 0x2192;
break;
case FRMDIR_HORI_RIGHT_TOP:
aPos = aRect.TopRight();
aPos.X() -= nAWidth;
aMove.Y() = 0;
aMove.X() *= -1;
cArrow = 0x2190;
break;
case FRMDIR_VERT_TOP_LEFT:
aPos = aRect.TopLeft();
aPos.X() += PixelToLogic(Point(1,1)).X();
aMove.X() = 0;
break;
case FRMDIR_VERT_TOP_RIGHT:
aPos = aRect.TopRight();
aPos.X() -= nAWidth;
aMove.X() = 0;
break;
}
sText.Append(cArrow);
for(sal_uInt16 i = 0; i < sText.Len(); i++)
{
String sDraw(sText.GetChar(i));
long nHDiff = 0;
long nCharWidth = GetTextWidth(sDraw);
sal_Bool bHorizontal = 0 == aMove.Y();
if(!bHorizontal)
{
nHDiff = (nAWidth - nCharWidth) / 2;
aPos.X() += nHDiff;
}
DrawText(aPos,sDraw);
if(bHorizontal)
{
aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth;
}
else
{
aPos.X() -= nHDiff;
aPos.Y() += aMove.Y();
}
}
aFont.SetSize(aSaveSize);
SetFont(aFont);
}
if(bTable)
{
// Tabelle malen, ggf. zentrieren
SetLineColor(Color(COL_LIGHTGRAY));
long nW = aRect.GetWidth(),nH = aRect.GetHeight();
long nTW = CELL_WIDTH * 3,nTH = CELL_HEIGHT * 3;
long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
Rectangle aCellRect(Point(_nLeft,_nTop),Size(CELL_WIDTH,CELL_HEIGHT));
for(sal_uInt16 i = 0; i < 3; ++i)
{
aCellRect.Left() = _nLeft;
aCellRect.Right() = _nLeft + CELL_WIDTH;
if(i > 0)
aCellRect.Move(0,CELL_HEIGHT);
for(sal_uInt16 j = 0; j < 3; ++j)
{
if(j > 0)
aCellRect.Move(CELL_WIDTH,0);
DrawRect(aCellRect);
}
}
}
}
//UUUU
void SvxPageWindow::drawFillAttributes(
const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
const Rectangle& rPaintRange,
const Rectangle& rDefineRange)
{
const basegfx::B2DRange aPaintRange(
rPaintRange.Left(),
rPaintRange.Top(),
rPaintRange.Right(),
rPaintRange.Bottom());
if(!aPaintRange.isEmpty() &&
!basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
!basegfx::fTools::equalZero(aPaintRange.getHeight()))
{
const basegfx::B2DRange aDefineRange(
rDefineRange.Left(),
rDefineRange.Top(),
rDefineRange.Right(),
rDefineRange.Bottom());
// prepare primitive sequence
drawinglayer::primitive2d::Primitive2DSequence aSequence;
// create fill geometry if there is something to fill
if(rFillAttributes.get() && rFillAttributes->isUsed())
{
aSequence = rFillAttributes->getPrimitive2DSequence(
aPaintRange,
aDefineRange);
}
// create line geometry if a LineColor is set at the target device
if(IsLineColor())
{
const drawinglayer::primitive2d::Primitive2DReference xOutline(
new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
basegfx::tools::createPolygonFromRect(aPaintRange),
GetLineColor().getBColor()));
drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
aSequence,
xOutline);
}
// draw that if we have something to draw
if(aSequence.getLength())
{
const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
basegfx::B2DHomMatrix(),
GetViewTransformation(),
aPaintRange,
0,
0.0,
com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >());
drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
*this,
aViewInformation2D);
if(pProcessor)
{
pProcessor->process(aSequence);
delete pProcessor;
}
}
}
}
// -----------------------------------------------------------------------
void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
{
delete pBorder;
pBorder = new SvxBoxItem(rNew);
}
// -----------------------------------------------------------------------
void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
{
delete pHdBorder;
pHdBorder = new SvxBoxItem(rNew);
}
// -----------------------------------------------------------------------
void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
{
delete pFtBorder;
pFtBorder = new SvxBoxItem(rNew);
}
void SvxPageWindow::EnableFrameDirection(sal_Bool bEnable)
{
bFrameDirection = bEnable;
}
void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
{
nFrameDirection = nDirection;
}
void SvxPageWindow::ResetBackground()
{
bResetBackground = sal_True;
}
//eof