1
0
Fork 0
libreoffice/sc/source/ui/view/gridmerg.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

225 lines
6.7 KiB
C++

/* -*- 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: */