Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/view/gridmerg.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <sal/config.h>
21
22
#include <vcl/lineinfo.hxx>
23
#include <vcl/outdev.hxx>
24
25
#include <gridmerg.hxx>
26
27
0
#define PAGEBREAK_LINE_DISTANCE_PIXEL 5
28
0
#define PAGEBREAK_LINE_DASH_LEN_PIXEL 5
29
0
#define PAGEBREAK_LINE_DASH_COUNT 1
30
31
ScGridMerger::ScGridMerger( OutputDevice* pOutDev, tools::Long nOnePixelX, tools::Long nOnePixelY )
32
0
    : pDev(pOutDev)
33
0
    , nOneX(nOnePixelX)
34
0
    , nOneY(nOnePixelY)
35
0
    , nFixStart(0)
36
0
    , nFixEnd(0)
37
0
    , nVarStart(0)
38
0
    , nVarDiff(0)
39
0
    , nCount(0)
40
0
    , bVertical(false)
41
0
{
42
    //  optimize (DrawGrid) only for pixel MapMode,
43
    //  to avoid rounding errors
44
45
0
    bOptimize = ( pDev->GetMapMode().GetMapUnit() == MapUnit::MapPixel );
46
0
}
47
48
ScGridMerger::~ScGridMerger()
49
0
{
50
0
    Flush();
51
0
}
52
53
void ScGridMerger::AddLine( tools::Long nStart, tools::Long nEnd, tools::Long nPos )
54
0
{
55
0
    if ( nCount )
56
0
    {
57
        //  not first line - test fix position
58
        //  more than one previous line - test distance
59
60
0
        if ( nStart != nFixStart || nEnd != nFixEnd )
61
0
        {
62
0
            if ( nCount == 1 && nPos == nVarStart &&
63
0
                    ( nStart == nFixEnd ||
64
0
                        nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
65
0
            {
66
                //  additional optimization: extend connected lines
67
                //  keep nCount at 1
68
0
                nFixEnd = nEnd;
69
0
            }
70
0
            else
71
0
                Flush();
72
0
        }
73
0
        else if ( nCount == 1 )
74
0
        {
75
0
            nVarDiff = nPos - nVarStart;
76
0
            ++nCount;
77
0
        }
78
0
        else if ( nPos != nVarStart + nCount * nVarDiff )       //! keep VarEnd?
79
0
            Flush();
80
0
        else
81
0
            ++nCount;
82
0
    }
83
84
0
    if ( !nCount )
85
0
    {
86
        //  first line (or flushed above) - just store
87
88
0
        nFixStart = nStart;
89
0
        nFixEnd   = nEnd;
90
0
        nVarStart = nPos;
91
0
        nVarDiff  = 0;
92
0
        nCount    = 1;
93
0
    }
94
0
}
95
96
void ScGridMerger::AddHorLine(bool bWorksInPixels, tools::Long nX1, tools::Long nX2, tools::Long nY, bool bDashed)
97
0
{
98
0
    if ( bWorksInPixels )
99
0
    {
100
0
        Point aPoint(pDev->PixelToLogic(Point(nX1, nY)));
101
0
        nX1 = aPoint.X();
102
0
        nY = aPoint.Y();
103
0
        nX2 = pDev->PixelToLogic(Point(nX2, 0)).X();
104
0
    }
105
106
0
    if ( bDashed )
107
0
    {
108
        // If there are some unflushed lines they must be flushed since
109
        // new line is of different style
110
0
        if (bOptimize) {
111
0
            Flush();
112
0
            bVertical = false;
113
0
        }
114
115
0
        LineInfo aLineInfo(LineStyle::Dash, 1);
116
0
        aLineInfo.SetDashCount( PAGEBREAK_LINE_DASH_COUNT );
117
118
        // Calculating logic values of DashLen and Distance from fixed pixel values
119
0
        Size aDashDistanceLen( pDev->PixelToLogic( Size( PAGEBREAK_LINE_DISTANCE_PIXEL,
120
0
                                                         PAGEBREAK_LINE_DASH_LEN_PIXEL )));
121
122
0
        aLineInfo.SetDistance( aDashDistanceLen.Width() );
123
0
        aLineInfo.SetDashLen( aDashDistanceLen.Height() );
124
125
0
        pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ), aLineInfo );
126
0
    }
127
0
    else if ( bOptimize )
128
0
    {
129
0
        if ( bVertical )
130
0
        {
131
0
            Flush();
132
0
            bVertical = false;
133
0
        }
134
0
        AddLine( nX1, nX2, nY );
135
0
    }
136
0
    else
137
0
        pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
138
0
}
139
140
void ScGridMerger::AddVerLine(bool bWorksInPixels, tools::Long nX, tools::Long nY1, tools::Long nY2, bool bDashed)
141
0
{
142
0
    if (bWorksInPixels)
143
0
    {
144
0
        Point aPoint(pDev->PixelToLogic(Point(nX, nY1)));
145
0
        nX = aPoint.X();
146
0
        nY1 = aPoint.Y();
147
0
        nY2 = pDev->PixelToLogic(Point(0, nY2)).Y();
148
0
    }
149
150
0
    if ( bDashed )
151
0
    {
152
        // If there are some unflushed lines they must be flushed since
153
        // new line is of different style
154
0
        if (bOptimize) {
155
0
            Flush();
156
0
            bVertical = false;
157
0
        }
158
159
0
        LineInfo aLineInfo(LineStyle::Dash, 1);
160
0
        aLineInfo.SetDashCount( PAGEBREAK_LINE_DASH_COUNT );
161
162
        // Calculating logic values of DashLen and Distance from fixed pixel values
163
0
        Size aDashDistanceLen( pDev->PixelToLogic( Size( PAGEBREAK_LINE_DISTANCE_PIXEL,
164
0
                                                         PAGEBREAK_LINE_DASH_LEN_PIXEL )));
165
166
0
        aLineInfo.SetDistance( aDashDistanceLen.Width() );
167
0
        aLineInfo.SetDashLen( aDashDistanceLen.Height() );
168
169
0
        pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ), aLineInfo);
170
0
    }
171
0
    else if ( bOptimize )
172
0
    {
173
0
        if ( !bVertical )
174
0
        {
175
0
            Flush();
176
0
            bVertical = true;
177
0
        }
178
0
        AddLine( nY1, nY2, nX );
179
0
    }
180
0
    else
181
0
        pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
182
0
}
183
184
void ScGridMerger::Flush()
185
0
{
186
0
    if (!nCount)
187
0
        return;
188
189
0
    if (bVertical)
190
0
    {
191
0
        if ( nCount == 1 )
192
0
            pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
193
0
        else
194
0
        {
195
0
            tools::Long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
196
0
            if ( nVarDiff < 0 )
197
0
            {
198
                //  nVarDiff is negative in RTL layout mode
199
                //  Change the positions so DrawGrid is called with a positive distance
200
                //  (nVarStart / nVarDiff can be modified, aren't used after Flush)
201
202
0
                nVarDiff = -nVarDiff;
203
0
                std::swap( nVarStart, nVarEnd );
204
0
            }
205
0
            pDev->DrawGrid( tools::Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
206
0
                            Size( nVarDiff, nFixEnd - nFixStart ),
207
0
                            DrawGridFlags::VertLines );
208
0
        }
209
0
    }
210
0
    else
211
0
    {
212
0
        if ( nCount == 1 )
213
0
            pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
214
0
        else
215
0
        {
216
0
            tools::Long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
217
0
            pDev->DrawGrid( tools::Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
218
0
                            Size( nFixEnd - nFixStart, nVarDiff ),
219
0
                            DrawGridFlags::HorzLines );
220
0
        }
221
0
    }
222
0
    nCount = 0;
223
0
}
224
225
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */