Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svtools/source/misc/unitconv.cxx
Line
Count
Source (jump to first uncovered line)
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 <o3tl/temporary.hxx>
21
#include <svtools/unitconv.hxx>
22
#include <tools/debug.hxx>
23
#include <tools/UnitConversion.hxx>
24
#include <vcl/outdev.hxx>
25
#include <vcl/weld.hxx>
26
27
void SetFieldUnit(weld::MetricSpinButton& rField, FieldUnit eUnit, bool bAll)
28
0
{
29
0
    sal_Int64 nMin, nMax;
30
0
    rField.get_range(nMin, nMax, FieldUnit::TWIP);
31
0
    sal_Int64 nValue = rField.get_value(FieldUnit::TWIP);
32
0
    nMin = rField.denormalize(nMin);
33
0
    nMax = rField.denormalize(nMax);
34
0
    nValue = rField.denormalize(nValue);
35
36
0
    if (!bAll)
37
0
    {
38
0
        switch (eUnit)
39
0
        {
40
0
            case FieldUnit::M:
41
0
            case FieldUnit::KM:
42
0
                eUnit = FieldUnit::CM;
43
0
                break;
44
0
            case FieldUnit::FOOT:
45
0
            case FieldUnit::MILE:
46
0
                eUnit = FieldUnit::INCH;
47
0
                break;
48
0
            default: //prevent warning
49
0
                break;
50
0
        }
51
0
    }
52
53
0
    rField.set_unit(eUnit);
54
55
0
    if (FieldUnit::POINT == eUnit)
56
0
    {
57
0
        if (rField.get_digits() > 1)
58
0
            rField.set_digits(1);
59
0
    }
60
0
    else
61
0
        rField.set_digits(2);
62
63
0
    switch (eUnit)
64
0
    {
65
        // _CHAR and _LINE sets the step of "char" and "line" unit, they are same as FieldUnit::MM
66
0
        case FieldUnit::CHAR:
67
0
        case FieldUnit::LINE:
68
0
        case FieldUnit::MM:
69
0
            rField.set_increments(50, 500, eUnit);
70
0
            break;
71
0
        case FieldUnit::INCH:
72
0
            rField.set_increments(2, 20, eUnit);
73
0
            break;
74
0
        default:
75
0
            rField.set_increments(10, 100, eUnit);
76
0
            break;
77
0
    }
78
79
0
    if (!bAll)
80
0
    {
81
0
        nMin = rField.normalize(nMin);
82
0
        nMax = rField.normalize(nMax);
83
0
        rField.set_range(nMin, nMax, FieldUnit::TWIP);
84
0
    }
85
86
0
    rField.set_value(rField.normalize(nValue), FieldUnit::TWIP);
87
0
}
88
89
void SetMetricValue(weld::MetricSpinButton& rField, sal_Int64 nCoreValue, MapUnit eUnit)
90
0
{
91
0
    sal_Int64 nVal = OutputDevice::LogicToLogic(nCoreValue, eUnit, MapUnit::Map100thMM);
92
0
    nVal = rField.normalize(nVal);
93
0
    rField.set_value(nVal, FieldUnit::MM_100TH);
94
0
}
95
96
sal_Int64 GetCoreValue(const weld::MetricSpinButton& rField, MapUnit eUnit)
97
0
{
98
0
    sal_Int64 nVal = rField.get_value(FieldUnit::MM_100TH);
99
    // avoid rounding issues
100
0
    const sal_Int64 nSizeMask = 0xffffffffff000000LL;
101
0
    bool bRoundBefore = true;
102
0
    if( nVal >= 0 )
103
0
    {
104
0
        if( (nVal & nSizeMask) == 0 )
105
0
            bRoundBefore = false;
106
0
    }
107
0
    else
108
0
    {
109
0
        if( ((-nVal) & nSizeMask ) == 0 )
110
0
            bRoundBefore = false;
111
0
    }
112
0
    if( bRoundBefore )
113
0
        nVal = rField.denormalize( nVal );
114
0
    sal_Int64 nUnitVal = OutputDevice::LogicToLogic(nVal, MapUnit::Map100thMM, eUnit);
115
0
    if (!bRoundBefore)
116
0
        nUnitVal = rField.denormalize(nUnitVal);
117
0
    return nUnitVal;
118
0
}
119
120
tools::Long CalcToUnit( float nIn, MapUnit eUnit )
121
0
{
122
    // nIn is in Points
123
124
0
    DBG_ASSERT( eUnit == MapUnit::MapTwip       ||
125
0
                eUnit == MapUnit::Map100thMM   ||
126
0
                eUnit == MapUnit::Map10thMM    ||
127
0
                eUnit == MapUnit::MapMM         ||
128
0
                eUnit == MapUnit::MapCM, "this unit is not implemented" );
129
130
0
    if (const auto eTo = MapToO3tlLength(eUnit); eTo != o3tl::Length::invalid)
131
0
        return std::round(o3tl::convert(nIn, o3tl::Length::pt, eTo));
132
133
0
    return 0;
134
0
}
135
136
137
tools::Long ItemToControl( tools::Long nIn, MapUnit eItem, FieldUnit eCtrl )
138
0
{
139
0
    const auto eFrom = MapToO3tlLength(eItem), eTo = FieldToO3tlLength(eCtrl);
140
0
    if (eFrom != o3tl::Length::invalid && eTo != o3tl::Length::invalid)
141
0
        return o3tl::convert(nIn, eFrom, eTo);
142
0
    return 0;
143
0
}
144
145
146
tools::Long ControlToItem( tools::Long nIn, FieldUnit eCtrl, MapUnit eItem )
147
0
{
148
0
    return ItemToControl( nIn, eItem, eCtrl );
149
0
}
150
151
152
FieldUnit MapToFieldUnit( const MapUnit eUnit )
153
0
{
154
0
    switch ( eUnit )
155
0
    {
156
0
        case MapUnit::Map100thMM:
157
0
        case MapUnit::Map10thMM:
158
0
        case MapUnit::MapMM:
159
0
            return FieldUnit::MM;
160
161
0
        case MapUnit::MapCM:
162
0
            return FieldUnit::CM;
163
164
0
        case MapUnit::Map1000thInch:
165
0
        case MapUnit::Map100thInch:
166
0
        case MapUnit::Map10thInch:
167
0
        case MapUnit::MapInch:
168
0
            return FieldUnit::INCH;
169
170
0
        case MapUnit::MapPoint:
171
0
            return FieldUnit::POINT;
172
173
0
        case MapUnit::MapTwip:
174
0
            return FieldUnit::TWIP;
175
0
        default: ;//prevent warning
176
0
    }
177
0
    return FieldUnit::NONE;
178
0
}
179
180
181
tools::Long CalcToPoint( tools::Long nIn, MapUnit eUnit, sal_uInt16 nFactor )
182
0
{
183
0
    DBG_ASSERT( eUnit == MapUnit::MapTwip       ||
184
0
                eUnit == MapUnit::Map100thMM   ||
185
0
                eUnit == MapUnit::Map10thMM    ||
186
0
                eUnit == MapUnit::MapMM         ||
187
0
                eUnit == MapUnit::MapCM, "this unit is not implemented" );
188
189
0
    if (const auto eFrom = MapToO3tlLength(eUnit); eFrom != o3tl::Length::invalid)
190
0
        return o3tl::convert(nIn * static_cast<sal_Int64>(nFactor), eFrom, o3tl::Length::pt);
191
0
    return 0;
192
0
}
193
194
195
tools::Long TransformMetric( tools::Long nVal, FieldUnit aOld, FieldUnit aNew )
196
0
{
197
0
    const auto eFrom = FieldToO3tlLength(aOld), eTo = FieldToO3tlLength(aNew);
198
0
    if (eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid)
199
0
        return nVal;
200
0
    return o3tl::convert(nVal, eFrom, eTo, o3tl::temporary(bool())); // Just 0 when overflown
201
0
}
202
203
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */