2014-04-14 21:54:43 +10:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* 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 .
|
|
|
|
*/
|
2014-04-27 05:07:47 -05:00
|
|
|
#include <sal/types.h>
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
#include <tools/poly.hxx>
|
2014-04-22 03:46:16 +10:00
|
|
|
#include <tools/helpers.hxx>
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
#include <vcl/virdev.hxx>
|
|
|
|
#include <vcl/outdev.hxx>
|
|
|
|
|
2014-04-27 05:07:47 -05:00
|
|
|
#include "salgdi.hxx"
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
void OutputDevice::DrawRect( const Rectangle& rRect )
|
|
|
|
{
|
|
|
|
if ( mpMetaFile )
|
|
|
|
mpMetaFile->AddAction( new MetaRectAction( rRect ) );
|
|
|
|
|
|
|
|
if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
|
|
|
|
|
|
|
|
if ( aRect.IsEmpty() )
|
|
|
|
return;
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
aRect.Justify();
|
|
|
|
|
2014-04-27 05:07:47 -05:00
|
|
|
if ( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if ( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if ( mbInitFillColor )
|
2014-04-27 19:38:55 +10:00
|
|
|
InitFillColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawRect( rRect );
|
|
|
|
}
|
|
|
|
|
|
|
|
void OutputDevice::DrawRect( const Rectangle& rRect,
|
|
|
|
sal_uLong nHorzRound, sal_uLong nVertRound )
|
|
|
|
{
|
|
|
|
if ( mpMetaFile )
|
|
|
|
mpMetaFile->AddAction( new MetaRoundRectAction( rRect, nHorzRound, nVertRound ) );
|
|
|
|
|
|
|
|
if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
const Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
|
|
|
|
|
|
|
|
if ( aRect.IsEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
nHorzRound = ImplLogicWidthToDevicePixel( nHorzRound );
|
|
|
|
nVertRound = ImplLogicHeightToDevicePixel( nVertRound );
|
|
|
|
|
|
|
|
// we need a graphics
|
|
|
|
if ( !mpGraphics )
|
|
|
|
{
|
2014-04-23 07:22:08 +10:00
|
|
|
if ( !AcquireGraphics() )
|
2014-04-14 21:54:43 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( mbInitClipRegion )
|
2014-04-25 02:43:06 +10:00
|
|
|
InitClipRegion();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if ( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( mbInitLineColor )
|
2014-04-22 00:40:20 +10:00
|
|
|
InitLineColor();
|
2014-04-27 05:07:47 -05:00
|
|
|
|
2014-04-14 21:54:43 +10:00
|
|
|
if ( mbInitFillColor )
|
2014-04-27 19:38:55 +10:00
|
|
|
InitFillColor();
|
2014-04-14 21:54:43 +10:00
|
|
|
|
|
|
|
if ( !nHorzRound && !nVertRound )
|
2014-04-27 05:07:47 -05:00
|
|
|
{
|
2014-04-14 21:54:43 +10:00
|
|
|
mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
|
2014-04-27 05:07:47 -05:00
|
|
|
}
|
2014-04-14 21:54:43 +10:00
|
|
|
else
|
|
|
|
{
|
|
|
|
const Polygon aRoundRectPoly( aRect, nHorzRound, nVertRound );
|
|
|
|
|
|
|
|
if ( aRoundRectPoly.GetSize() >= 2 )
|
|
|
|
{
|
|
|
|
const SalPoint* pPtAry = (const SalPoint*) aRoundRectPoly.GetConstPointAry();
|
|
|
|
|
|
|
|
if ( !mbFillColor )
|
|
|
|
mpGraphics->DrawPolyLine( aRoundRectPoly.GetSize(), pPtAry, this );
|
|
|
|
else
|
|
|
|
mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry, this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawRect( rRect, nHorzRound, nVertRound );
|
|
|
|
}
|
2014-04-22 03:33:26 +10:00
|
|
|
|
2014-04-28 20:47:12 +10:00
|
|
|
void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
|
|
|
|
{
|
|
|
|
Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
|
|
|
|
aDstRect.Intersection( rRect );
|
|
|
|
|
|
|
|
if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( !mpGraphics && !AcquireGraphics() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( mbInitClipRegion )
|
|
|
|
InitClipRegion();
|
|
|
|
|
|
|
|
if( mbOutputClipped )
|
|
|
|
return;
|
|
|
|
|
|
|
|
const long nDistX = std::max( rDist.Width(), 1L );
|
|
|
|
const long nDistY = std::max( rDist.Height(), 1L );
|
|
|
|
long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
|
|
|
|
long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
|
|
|
|
const long nRight = aDstRect.Right();
|
|
|
|
const long nBottom = aDstRect.Bottom();
|
|
|
|
const long nStartX = ImplLogicXToDevicePixel( nX );
|
|
|
|
const long nEndX = ImplLogicXToDevicePixel( nRight );
|
|
|
|
const long nStartY = ImplLogicYToDevicePixel( nY );
|
|
|
|
const long nEndY = ImplLogicYToDevicePixel( nBottom );
|
|
|
|
long nHorzCount = 0L;
|
|
|
|
long nVertCount = 0L;
|
|
|
|
|
|
|
|
css::uno::Sequence< sal_Int32 > aVertBuf;
|
|
|
|
css::uno::Sequence< sal_Int32 > aHorzBuf;
|
|
|
|
|
|
|
|
if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
|
|
|
|
{
|
|
|
|
aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
|
|
|
|
aVertBuf[ nVertCount++ ] = nStartY;
|
|
|
|
while( ( nY += nDistY ) <= nBottom )
|
|
|
|
{
|
|
|
|
aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
|
|
|
|
{
|
|
|
|
aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
|
|
|
|
aHorzBuf[ nHorzCount++ ] = nStartX;
|
|
|
|
while( ( nX += nDistX ) <= nRight )
|
|
|
|
{
|
|
|
|
aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( mbInitLineColor )
|
|
|
|
InitLineColor();
|
|
|
|
|
|
|
|
if( mbInitFillColor )
|
|
|
|
InitFillColor();
|
|
|
|
|
|
|
|
const bool bOldMap = mbMap;
|
|
|
|
EnableMapMode( false );
|
|
|
|
|
|
|
|
if( nFlags & GRID_DOTS )
|
|
|
|
{
|
|
|
|
for( long i = 0L; i < nVertCount; i++ )
|
|
|
|
{
|
|
|
|
for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
|
|
|
|
{
|
|
|
|
mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( nFlags & GRID_HORZLINES )
|
|
|
|
{
|
|
|
|
for( long i = 0L; i < nVertCount; i++ )
|
|
|
|
{
|
|
|
|
nY = aVertBuf[ i ];
|
|
|
|
mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( nFlags & GRID_VERTLINES )
|
|
|
|
{
|
|
|
|
for( long i = 0L; i < nHorzCount; i++ )
|
|
|
|
{
|
|
|
|
nX = aHorzBuf[ i ];
|
|
|
|
mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EnableMapMode( bOldMap );
|
|
|
|
|
|
|
|
if( mpAlphaVDev )
|
|
|
|
mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
|
|
|
|
}
|
|
|
|
|
2014-04-22 03:33:26 +10:00
|
|
|
sal_uLong AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
|
|
|
|
{
|
|
|
|
sal_uLong nMirrFlags = 0;
|
|
|
|
|
|
|
|
if ( rTwoRect.mnDestWidth < 0 )
|
|
|
|
{
|
|
|
|
rTwoRect.mnSrcX = rSizePix.Width() - rTwoRect.mnSrcX - rTwoRect.mnSrcWidth;
|
|
|
|
rTwoRect.mnDestWidth = -rTwoRect.mnDestWidth;
|
|
|
|
rTwoRect.mnDestX -= rTwoRect.mnDestWidth-1;
|
|
|
|
nMirrFlags |= BMP_MIRROR_HORZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( rTwoRect.mnDestHeight < 0 )
|
|
|
|
{
|
|
|
|
rTwoRect.mnSrcY = rSizePix.Height() - rTwoRect.mnSrcY - rTwoRect.mnSrcHeight;
|
|
|
|
rTwoRect.mnDestHeight = -rTwoRect.mnDestHeight;
|
|
|
|
rTwoRect.mnDestY -= rTwoRect.mnDestHeight-1;
|
|
|
|
nMirrFlags |= BMP_MIRROR_VERT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ( rTwoRect.mnSrcX < 0 ) || ( rTwoRect.mnSrcX >= rSizePix.Width() ) ||
|
|
|
|
( rTwoRect.mnSrcY < 0 ) || ( rTwoRect.mnSrcY >= rSizePix.Height() ) ||
|
|
|
|
( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rSizePix.Width() ) ||
|
|
|
|
( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rSizePix.Height() ) )
|
|
|
|
{
|
|
|
|
const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
|
|
|
|
Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
|
2014-04-27 05:07:47 -05:00
|
|
|
Rectangle aCropRect( aSourceRect );
|
2014-04-22 03:33:26 +10:00
|
|
|
|
|
|
|
aCropRect.Intersection( Rectangle( Point(), rSizePix ) );
|
|
|
|
|
|
|
|
if( aCropRect.IsEmpty() )
|
2014-04-27 05:07:47 -05:00
|
|
|
{
|
2014-04-22 03:33:26 +10:00
|
|
|
rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
|
2014-04-27 05:07:47 -05:00
|
|
|
}
|
2014-04-22 03:33:26 +10:00
|
|
|
else
|
|
|
|
{
|
2014-04-27 05:07:47 -05:00
|
|
|
const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
|
|
|
|
const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
|
2014-04-22 03:33:26 +10:00
|
|
|
|
|
|
|
const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
|
|
|
|
const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
|
|
|
|
const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
|
|
|
|
const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
|
|
|
|
|
|
|
|
rTwoRect.mnSrcX = aCropRect.Left();
|
|
|
|
rTwoRect.mnSrcY = aCropRect.Top();
|
|
|
|
rTwoRect.mnSrcWidth = aCropRect.GetWidth();
|
|
|
|
rTwoRect.mnSrcHeight = aCropRect.GetHeight();
|
|
|
|
rTwoRect.mnDestX = nDstX1;
|
|
|
|
rTwoRect.mnDestY = nDstY1;
|
|
|
|
rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
|
|
|
|
rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nMirrFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdjustTwoRect( SalTwoRect& rTwoRect, const Rectangle& rValidSrcRect )
|
|
|
|
{
|
|
|
|
if( ( rTwoRect.mnSrcX < rValidSrcRect.Left() ) || ( rTwoRect.mnSrcX >= rValidSrcRect.Right() ) ||
|
|
|
|
( rTwoRect.mnSrcY < rValidSrcRect.Top() ) || ( rTwoRect.mnSrcY >= rValidSrcRect.Bottom() ) ||
|
|
|
|
( ( rTwoRect.mnSrcX + rTwoRect.mnSrcWidth ) > rValidSrcRect.Right() ) ||
|
|
|
|
( ( rTwoRect.mnSrcY + rTwoRect.mnSrcHeight ) > rValidSrcRect.Bottom() ) )
|
|
|
|
{
|
|
|
|
const Rectangle aSourceRect( Point( rTwoRect.mnSrcX, rTwoRect.mnSrcY ),
|
|
|
|
Size( rTwoRect.mnSrcWidth, rTwoRect.mnSrcHeight ) );
|
2014-04-27 05:07:47 -05:00
|
|
|
Rectangle aCropRect( aSourceRect );
|
2014-04-22 03:33:26 +10:00
|
|
|
|
|
|
|
aCropRect.Intersection( rValidSrcRect );
|
|
|
|
|
|
|
|
if( aCropRect.IsEmpty() )
|
2014-04-27 05:07:47 -05:00
|
|
|
{
|
2014-04-22 03:33:26 +10:00
|
|
|
rTwoRect.mnSrcWidth = rTwoRect.mnSrcHeight = rTwoRect.mnDestWidth = rTwoRect.mnDestHeight = 0;
|
2014-04-27 05:07:47 -05:00
|
|
|
}
|
2014-04-22 03:33:26 +10:00
|
|
|
else
|
|
|
|
{
|
2014-04-27 05:07:47 -05:00
|
|
|
const double fFactorX = ( rTwoRect.mnSrcWidth > 1 ) ? (double) ( rTwoRect.mnDestWidth - 1 ) / ( rTwoRect.mnSrcWidth - 1 ) : 0.0;
|
|
|
|
const double fFactorY = ( rTwoRect.mnSrcHeight > 1 ) ? (double) ( rTwoRect.mnDestHeight - 1 ) / ( rTwoRect.mnSrcHeight - 1 ) : 0.0;
|
2014-04-22 03:33:26 +10:00
|
|
|
|
|
|
|
const long nDstX1 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Left() - rTwoRect.mnSrcX ) );
|
|
|
|
const long nDstY1 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Top() - rTwoRect.mnSrcY ) );
|
|
|
|
const long nDstX2 = rTwoRect.mnDestX + FRound( fFactorX * ( aCropRect.Right() - rTwoRect.mnSrcX ) );
|
|
|
|
const long nDstY2 = rTwoRect.mnDestY + FRound( fFactorY * ( aCropRect.Bottom() - rTwoRect.mnSrcY ) );
|
|
|
|
|
|
|
|
rTwoRect.mnSrcX = aCropRect.Left();
|
|
|
|
rTwoRect.mnSrcY = aCropRect.Top();
|
|
|
|
rTwoRect.mnSrcWidth = aCropRect.GetWidth();
|
|
|
|
rTwoRect.mnSrcHeight = aCropRect.GetHeight();
|
|
|
|
rTwoRect.mnDestX = nDstX1;
|
|
|
|
rTwoRect.mnDestY = nDstY1;
|
|
|
|
rTwoRect.mnDestWidth = nDstX2 - nDstX1 + 1;
|
|
|
|
rTwoRect.mnDestHeight = nDstY2 - nDstY1 + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|