Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/tools/source/generic/gen.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
#include <rtl/string.hxx>
22
23
#include <algorithm>
24
#include <tuple>
25
#include <o3tl/hash_combine.hxx>
26
#include <o3tl/safeint.hxx>
27
#include <tools/gen.hxx>
28
29
OString Pair::toString() const
30
0
{
31
    // Note that this is not just used for debugging output but the
32
    // format is parsed by external code (passed in callbacks to
33
    // LibreOfficeKit clients). So don't change.
34
0
    return OString::number(A()) + ", " + OString::number(B());
35
0
}
36
37
size_t Pair::GetHashValue() const
38
27.7M
{
39
27.7M
    size_t hash = 0;
40
27.7M
    o3tl::hash_combine( hash, mnA );
41
27.7M
    o3tl::hash_combine( hash, mnB );
42
27.7M
    return hash;
43
27.7M
}
44
45
void RectangleTemplateBase::SaturatingSetSize(const SizeTemplateBase& rSize)
46
85.6k
{
47
85.6k
    if (rSize.Width() < 0)
48
17.1k
        mnRight = o3tl::saturating_add(mnLeft, (rSize.Width() + 1));
49
68.5k
    else if ( rSize.Width() > 0 )
50
56.9k
        mnRight = o3tl::saturating_add(mnLeft, (rSize.Width() - 1));
51
11.6k
    else
52
11.6k
        SetWidthEmpty();
53
54
85.6k
    if ( rSize.Height() < 0 )
55
16.1k
        mnBottom = o3tl::saturating_add(mnTop, (rSize.Height() + 1));
56
69.4k
    else if ( rSize.Height() > 0 )
57
57.9k
        mnBottom = o3tl::saturating_add(mnTop, (rSize.Height() - 1));
58
11.4k
    else
59
11.4k
        SetHeightEmpty();
60
85.6k
}
61
62
void RectangleTemplateBase::SaturatingSetPosX(tools::Long x)
63
55
{
64
55
    if (!IsWidthEmpty())
65
55
        mnRight = o3tl::saturating_add(mnRight, x - mnLeft);
66
55
    mnLeft = x;
67
55
}
68
69
void RectangleTemplateBase::SaturatingSetPosY(tools::Long y)
70
56
{
71
56
    if (!IsHeightEmpty())
72
56
        mnBottom = o3tl::saturating_add(mnBottom, y - mnTop);
73
56
    mnTop = y;
74
56
}
75
76
void RectangleTemplateBase::Union( const RectangleTemplateBase& rRect )
77
38.8M
{
78
38.8M
    if ( rRect.IsEmpty() )
79
4.72M
        return;
80
81
34.0M
    if ( IsEmpty() )
82
3.38M
        *this = rRect;
83
30.7M
    else
84
30.7M
    {
85
30.7M
        std::tie(mnLeft, mnRight) = std::minmax({ mnLeft, rRect.mnLeft, mnRight, rRect.mnRight });
86
30.7M
        std::tie(mnTop, mnBottom) = std::minmax({ mnTop, rRect.mnTop, mnBottom, rRect.mnBottom });
87
30.7M
    }
88
34.0M
}
89
90
void RectangleTemplateBase::Intersection( const RectangleTemplateBase& rRect )
91
122k
{
92
122k
    if ( IsEmpty() )
93
14.0k
        return;
94
108k
    if ( rRect.IsEmpty() )
95
39.8k
    {
96
39.8k
        *this = tools::Rectangle();
97
39.8k
        return;
98
39.8k
    }
99
100
    // Normalize rectangle
101
68.4k
    RectangleTemplateBase aTmpRect( rRect );
102
68.4k
    Normalize();
103
68.4k
    aTmpRect.Normalize();
104
105
    // Perform intersection
106
68.4k
    mnLeft  = std::max( mnLeft, aTmpRect.mnLeft );
107
68.4k
    mnRight = std::min( mnRight, aTmpRect.mnRight );
108
68.4k
    mnTop   = std::max( mnTop, aTmpRect.mnTop );
109
68.4k
    mnBottom= std::min( mnBottom, aTmpRect.mnBottom );
110
111
    // Determine if intersection is empty
112
68.4k
    if ( mnRight < mnLeft || mnBottom < mnTop )
113
1.52k
        *this = tools::Rectangle();
114
68.4k
}
115
116
void RectangleTemplateBase::Normalize()
117
1.98M
{
118
1.98M
    if ((mnRight < mnLeft) && (!IsWidthEmpty()))
119
23.1k
    {
120
23.1k
        std::swap(mnLeft, mnRight);
121
23.1k
    }
122
123
1.98M
    if ((mnBottom < mnTop) && (!IsHeightEmpty()))
124
34.9k
    {
125
34.9k
        std::swap(mnBottom, mnTop);
126
34.9k
    }
127
1.98M
}
128
129
bool RectangleTemplateBase::Contains( const PointTemplateBase& rPoint ) const
130
64.0k
{
131
64.0k
    if ( IsEmpty() )
132
14.0k
        return false;
133
134
50.0k
    if ( mnLeft <= mnRight )
135
50.0k
    {
136
50.0k
        if ( (rPoint.X() < mnLeft) || (rPoint.X() > mnRight) )
137
96
            return false;
138
50.0k
    }
139
0
    else
140
0
    {
141
0
        if ( (rPoint.X() > mnLeft) || (rPoint.X() < mnRight) )
142
0
            return false;
143
0
    }
144
49.9k
    if ( mnTop <= mnBottom )
145
49.9k
    {
146
49.9k
        if ( (rPoint.Y() < mnTop) || (rPoint.Y() > mnBottom) )
147
48.2k
            return false;
148
49.9k
    }
149
0
    else
150
0
    {
151
0
        if ( (rPoint.Y() > mnTop) || (rPoint.Y() < mnBottom) )
152
0
            return false;
153
0
    }
154
1.65k
    return true;
155
49.9k
}
156
157
bool RectangleTemplateBase::Contains( const RectangleTemplateBase& rRect ) const
158
94
{
159
94
    return Contains( PointTemplateBase{ rRect.Left(), rRect.Top() } )
160
0
        && Contains( PointTemplateBase{ rRect.Right(), rRect.Bottom() } );
161
94
}
162
163
bool RectangleTemplateBase::Overlaps( const RectangleTemplateBase& rRect ) const
164
18.3k
{
165
    // If there's no intersection, they don't overlap
166
18.3k
    RectangleTemplateBase aTmp(*this);
167
18.3k
    aTmp.Intersection(rRect);
168
18.3k
    return !aTmp.IsEmpty();
169
18.3k
}
170
171
OString RectangleTemplateBase::toString() const
172
0
{
173
    // Note that this is not just used for debugging output but the
174
    // format is parsed by external code (passed in callbacks to
175
    // LibreOfficeKit clients). So don't change.
176
0
    return OString::number(Left()) + ", "
177
0
            + OString::number(Top()) + ", "
178
0
            + OString::number(getOpenWidth()) + ", "
179
0
            + OString::number(getOpenHeight());
180
0
}
181
182
void RectangleTemplateBase::expand(tools::Long nExpandBy)
183
0
{
184
0
    AdjustLeft(-nExpandBy);
185
0
    AdjustTop(-nExpandBy);
186
0
    AdjustRight(nExpandBy);
187
0
    AdjustBottom(nExpandBy);
188
0
}
189
190
void RectangleTemplateBase::shrink(tools::Long nShrinkBy)
191
0
{
192
0
    mnLeft   += nShrinkBy;
193
0
    mnTop    += nShrinkBy;
194
0
    if (!IsWidthEmpty())
195
0
        mnRight -= nShrinkBy;
196
0
    if (!IsHeightEmpty())
197
0
        mnBottom -= nShrinkBy;
198
0
}
199
200
tools::Long RectangleTemplateBase::AdjustRight(tools::Long nHorzMoveDelta)
201
178M
{
202
178M
    if (IsWidthEmpty())
203
936
        mnRight = mnLeft + nHorzMoveDelta - 1;
204
178M
    else
205
178M
        mnRight += nHorzMoveDelta;
206
178M
    return mnRight;
207
178M
}
208
209
tools::Long RectangleTemplateBase::AdjustBottom( tools::Long nVertMoveDelta )
210
450k
{
211
450k
    if (IsHeightEmpty())
212
903
        mnBottom = mnTop + nVertMoveDelta - 1;
213
449k
    else
214
449k
        mnBottom += nVertMoveDelta;
215
450k
    return mnBottom;
216
450k
}
217
218
static_assert( std::is_trivially_copyable< Pair >::value );
219
static_assert( std::is_trivially_copyable< Point >::value );
220
static_assert( std::is_trivially_copyable< Size >::value );
221
static_assert( std::is_trivially_copyable< Range >::value );
222
static_assert( std::is_trivially_copyable< Selection >::value );
223
static_assert( std::is_trivially_copyable< tools::Rectangle >::value );
224
225
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */