include/o3tl/unit_conversion.hxx         |   20 ++++++++++++++++++++
 include/oox/drawingml/drawingmltypes.hxx |    4 +---
 2 files changed, 21 insertions(+), 3 deletions(-)

New commits:
commit ae04cfdbad1f4c09b06cd2cee9d89e9909181acc
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Mon Aug 23 16:28:10 2021 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Tue Aug 24 10:37:21 2021 +0200

    Introduce convertNarrowing to return smaller integer types
    
    It will use compile-type constants to clamp input value, instead of
    clamping more expensive pre-sanitized output value.
    
    Change-Id: If78f8b1b4c99bd2f16b1d8a71872e89a0dddd8d0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120874
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/include/o3tl/unit_conversion.hxx b/include/o3tl/unit_conversion.hxx
index cf293662e7b2..7bee0ed397e5 100644
--- a/include/o3tl/unit_conversion.hxx
+++ b/include/o3tl/unit_conversion.hxx
@@ -221,6 +221,26 @@ template <typename N, typename U> constexpr auto 
convertSaturate(N n, U from, U
     return detail::MulDivSaturate(n, detail::md(from, to), detail::md(to, 
from));
 }
 
+// Conversion with saturation (only for integral types), optimized for return 
types smaller than
+// sal_Int64. In this case, it's easier to clamp input values to known bounds, 
than to do some
+// preprocessing to handle too large input values, just to clamp the result 
anyway. Use it like:
+//
+//     sal_Int32 n = convertNarrowing<sal_Int32, o3tl::Length::mm100, 
o3tl::Length::emu>(m);
+template <typename Out, auto from, auto to, typename N,
+          std::enable_if_t<
+              std::is_integral_v<N> && std::is_integral_v<Out> && sizeof(Out) 
< sizeof(sal_Int64),
+              int> = 0>
+constexpr Out convertNarrowing(N n)
+{
+    constexpr sal_Int64 nMin = 
convertSaturate(std::numeric_limits<Out>::min(), to, from);
+    constexpr sal_Int64 nMax = 
convertSaturate(std::numeric_limits<Out>::max(), to, from);
+    if (static_cast<sal_Int64>(n) > nMax)
+        return std::numeric_limits<Out>::max();
+    if (static_cast<sal_Int64>(n) < nMin)
+        return std::numeric_limits<Out>::min();
+    return convert(n, from, to);
+}
+
 // Return a pair { multiplier, divisor } for a given conversion
 template <typename U> constexpr std::pair<sal_Int64, sal_Int64> 
getConversionMulDiv(U from, U to)
 {
diff --git a/include/oox/drawingml/drawingmltypes.hxx 
b/include/oox/drawingml/drawingmltypes.hxx
index 05d218fa882e..4350b8d033a7 100644
--- a/include/oox/drawingml/drawingmltypes.hxx
+++ b/include/oox/drawingml/drawingmltypes.hxx
@@ -180,9 +180,7 @@ inline sal_Int64 convertHmmToEmu( sal_Int32 nValue )
 /** Converts the passed 64-bit integer value from EMUs to 1/100 mm. */
 inline sal_Int32 convertEmuToHmm( sal_Int64 nValue )
 {
-    return getLimitedValue<sal_Int32, sal_Int64>(
-        o3tl::convertSaturate(nValue, o3tl::Length::emu, o3tl::Length::mm100), 
SAL_MIN_INT32,
-        SAL_MAX_INT32);
+    return o3tl::convertNarrowing<sal_Int32, o3tl::Length::emu, 
o3tl::Length::mm100>(nValue);
 }
 
 /** Converts the passed 64-bit integer value from EMUs to Points. */

Reply via email to