blob: 2324d0a7441bbae08b8b490271a0398e8280e07e [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_sc.hxx"
#include <vcl/outdev.hxx>
#include "gridmerg.hxx"
//------------------------------------------------------------------
ScGridMerger::ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY ) :
pDev( pOutDev ),
nOneX( nOnePixelX ),
nOneY( nOnePixelY ),
nCount( 0 ),
bVertical( sal_False )
{
// optimize (DrawGrid) only for pixel MapMode,
// to avoid rounding errors
bOptimize = ( pDev->GetMapMode().GetMapUnit() == MAP_PIXEL );
}
ScGridMerger::~ScGridMerger()
{
Flush();
}
void ScGridMerger::AddLine( long nStart, long nEnd, long nPos )
{
if ( nCount )
{
// not first line - test fix position
// more than one previous line - test distance
if ( nStart != nFixStart || nEnd != nFixEnd )
{
if ( nCount == 1 && nPos == nVarStart &&
( nStart == nFixEnd ||
nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
{
// additional optimization: extend connected lines
// keep nCount at 1
nFixEnd = nEnd;
}
else
Flush();
}
else if ( nCount == 1 )
{
nVarDiff = nPos - nVarStart;
++nCount;
}
else if ( nPos != nVarStart + nCount * nVarDiff ) //! keep VarEnd?
Flush();
else
++nCount;
}
if ( !nCount )
{
// first line (or flushed above) - just store
nFixStart = nStart;
nFixEnd = nEnd;
nVarStart = nPos;
nVarDiff = 0;
nCount = 1;
}
}
void ScGridMerger::AddHorLine( long nX1, long nX2, long nY )
{
if ( bOptimize )
{
if ( bVertical )
{
Flush();
bVertical = sal_False;
}
AddLine( nX1, nX2, nY );
}
else
pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
}
void ScGridMerger::AddVerLine( long nX, long nY1, long nY2 )
{
if ( bOptimize )
{
if ( !bVertical )
{
Flush();
bVertical = sal_True;
}
AddLine( nY1, nY2, nX );
}
else
pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
}
void ScGridMerger::Flush()
{
if (nCount)
{
if (bVertical)
{
if ( nCount == 1 )
pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
else
{
long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
if ( nVarDiff < 0 )
{
// nVarDiff is negative in RTL layout mode
// Change the positions so DrawGrid is called with a positive distance
// (nVarStart / nVarDiff can be modified, aren't used after Flush)
nVarDiff = -nVarDiff;
long nTemp = nVarStart;
nVarStart = nVarEnd;
nVarEnd = nTemp;
}
pDev->DrawGrid( Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
Size( nVarDiff, nFixEnd - nFixStart ),
GRID_VERTLINES );
}
}
else
{
if ( nCount == 1 )
pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
else
{
long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
pDev->DrawGrid( Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
Size( nFixEnd - nFixStart, nVarDiff ),
GRID_HORZLINES );
}
}
nCount = 0;
}
}