/* -*- 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 .
*/
#include <sal/config.h>
#include <vcl/lineinfo.hxx>
#include <vcl/outdev.hxx>
#include <gridmerg.hxx>
#define PAGEBREAK_LINE_DISTANCE_PIXEL 5
#define PAGEBREAK_LINE_DASH_LEN_PIXEL 5
#define PAGEBREAK_LINE_DASH_COUNT 1
ScGridMerger::ScGridMerger( OutputDevice* pOutDev, tools::Long nOnePixelX, tools::Long nOnePixelY )
: pDev(pOutDev)
, nOneX(nOnePixelX)
, nOneY(nOnePixelY)
, nFixStart(0 )
, nFixEnd(0 )
, nVarStart(0 )
, nVarDiff(0 )
, nCount(0 )
, bVertical(false )
{
// optimize (DrawGrid) only for pixel MapMode,
// to avoid rounding errors
bOptimize = ( pDev->GetMapMode().GetMapUnit() == MapUnit::MapPixel );
}
ScGridMerger::~ScGridMerger()
{
Flush();
}
void ScGridMerger::AddLine( tools::Long nStart, tools::Long nEnd, tools::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(bool bWorksInPixels, tools::Long nX1, tools::Long nX2, tools::Long nY, bool bDashed)
{
if ( bWorksInPixels )
{
Point aPoint(pDev->PixelToLogic(Point(nX1, nY)));
nX1 = aPoint.X();
nY = aPoint.Y();
nX2 = pDev->PixelToLogic(Point(nX2, 0 )).X();
}
if ( bDashed )
{
// If there are some unflushed lines they must be flushed since
// new line is of different style
if (bOptimize) {
Flush();
bVertical = false ;
}
LineInfo aLineInfo(LineStyle::Dash, 1 );
aLineInfo.SetDashCount( PAGEBREAK_LINE_DASH_COUNT );
// Calculating logic values of DashLen and Distance from fixed pixel values
Size aDashDistanceLen( pDev->PixelToLogic( Size( PAGEBREAK_LINE_DISTANCE_PIXEL,
PAGEBREAK_LINE_DASH_LEN_PIXEL )));
aLineInfo.SetDistance( aDashDistanceLen.Width() );
aLineInfo.SetDashLen( aDashDistanceLen.Height() );
pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ), aLineInfo );
}
else if ( bOptimize )
{
if ( bVertical )
{
Flush();
bVertical = false ;
}
AddLine( nX1, nX2, nY );
}
else
pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
}
void ScGridMerger::AddVerLine(bool bWorksInPixels, tools::Long nX, tools::Long nY1, tools::Long nY2, bool bDashed)
{
if (bWorksInPixels)
{
Point aPoint(pDev->PixelToLogic(Point(nX, nY1)));
nX = aPoint.X();
nY1 = aPoint.Y();
nY2 = pDev->PixelToLogic(Point(0 , nY2)).Y();
}
if ( bDashed )
{
// If there are some unflushed lines they must be flushed since
// new line is of different style
if (bOptimize) {
Flush();
bVertical = false ;
}
LineInfo aLineInfo(LineStyle::Dash, 1 );
aLineInfo.SetDashCount( PAGEBREAK_LINE_DASH_COUNT );
// Calculating logic values of DashLen and Distance from fixed pixel values
Size aDashDistanceLen( pDev->PixelToLogic( Size( PAGEBREAK_LINE_DISTANCE_PIXEL,
PAGEBREAK_LINE_DASH_LEN_PIXEL )));
aLineInfo.SetDistance( aDashDistanceLen.Width() );
aLineInfo.SetDashLen( aDashDistanceLen.Height() );
pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ), aLineInfo);
}
else if ( bOptimize )
{
if ( !bVertical )
{
Flush();
bVertical = true ;
}
AddLine( nY1, nY2, nX );
}
else
pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
}
void ScGridMerger::Flush()
{
if (!nCount)
return ;
if (bVertical)
{
if ( nCount == 1 )
pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
else
{
tools::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;
std::swap( nVarStart, nVarEnd );
}
pDev->DrawGrid( tools::Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
Size( nVarDiff, nFixEnd - nFixStart ),
DrawGridFlags::VertLines );
}
}
else
{
if ( nCount == 1 )
pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
else
{
tools::Long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
pDev->DrawGrid( tools::Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
Size( nFixEnd - nFixStart, nVarDiff ),
DrawGridFlags::HorzLines );
}
}
nCount = 0 ;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=92 H=96 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland