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