LibreOffice Module oox (master)  1
helper.hxx
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 #ifndef INCLUDED_OOX_HELPER_HELPER_HXX
21 #define INCLUDED_OOX_HELPER_HELPER_HXX
22 
23 #include <sal/config.h>
24 
25 #include <cstring>
26 #include <limits>
27 
28 #include <o3tl/safeint.hxx>
29 #include <osl/endian.h>
30 #include <rtl/math.hxx>
31 #include <sal/macros.h>
32 #include <sal/types.h>
33 #include <tools/color.hxx>
34 
35 namespace oox {
36 
37 // Helper macros ==============================================================
38 
39 namespace detail {
40 
41 //TODO: Temporary helper for STATIC_ARRAY_SELECT; ultimately, the latter should be replaced by a
42 // proper function (template):
43 template<typename T> constexpr std::make_unsigned_t<T> make_unsigned(T value) {
44  if constexpr (std::is_signed_v<T>) {
45  return o3tl::make_unsigned(value);
46  } else {
47  return value;
48  }
49 }
50 
51 }
52 
55 #define STATIC_ARRAY_SELECT( array, index, def ) \
56  ((detail::make_unsigned(index) < SAL_N_ELEMENTS(array)) ? ((array)[static_cast<size_t>(index)]) : (def))
57 
58 // Common constants ===========================================================
59 
79 
80 
81 const ::Color API_RGB_TRANSPARENT (ColorTransparency, 0xffffffff);
82 const sal_uInt32 UNSIGNED_RGB_TRANSPARENT = static_cast<sal_uInt32>(-1);
83 const ::Color API_RGB_BLACK (0x000000);
84 const ::Color API_RGB_GRAY (0x808080);
85 const ::Color API_RGB_WHITE (0xFFFFFF);
86 
87 const sal_Int16 API_LINE_SOLID = 0;
88 const sal_Int16 API_LINE_DOTTED = 1;
89 const sal_Int16 API_LINE_DASHED = 2;
90 const sal_Int16 API_FINE_LINE_DASHED = 14;
91 
92 const sal_Int16 API_LINE_NONE = 0;
93 const sal_Int16 API_LINE_HAIR = 2;
94 const sal_Int16 API_LINE_THIN = 35;
95 const sal_Int16 API_LINE_MEDIUM = 88;
96 const sal_Int16 API_LINE_THICK = 141;
97 
98 const sal_Int16 API_ESCAPE_NONE = 0;
99 const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101;
100 const sal_Int16 API_ESCAPE_SUBSCRIPT = -101;
101 
104 
105 
106 // Limitate values ------------------------------------------------------------
107 
108 template< typename ReturnType, typename Type >
109 inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax )
110 {
111  return static_cast< ReturnType >( ::std::clamp( nValue, nMin, nMax ) );
112 }
113 
114 template< typename ReturnType, typename Type >
115 inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd )
116 {
117  static_assert(::std::numeric_limits< Type >::is_integer, "is integer");
118  Type nInterval = nEnd - nBegin;
119  Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval);
120  return static_cast< ReturnType >( nValue - nCount * nInterval );
121 }
122 
123 template< typename ReturnType >
124 inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd )
125 {
126  double fInterval = fEnd - fBegin;
127  double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval );
128  return static_cast< ReturnType >( fValue - fCount * fInterval );
129 }
130 
131 // Read from bitfields --------------------------------------------------------
132 
134 template< typename Type >
135 inline bool getFlag( Type nBitField, Type nMask )
136 {
137  return (nBitField & nMask) != 0;
138 }
139 
141 template< typename ReturnType, typename Type >
142 inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
143 {
144  return getFlag( nBitField, nMask ) ? nSet : nUnset;
145 }
146 
154 template< typename ReturnType, typename Type >
155 inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
156 {
157  sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
158  return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) );
159 }
160 
161 // Write to bitfields ---------------------------------------------------------
162 
164 template< typename Type >
165 inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true )
166 {
167  if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask;
168 }
169 
170 
173 template< typename Type >
174 class OptValue
175 {
176 public:
177  OptValue() : maValue(), mbHasValue( false ) {}
178  explicit OptValue( const Type& rValue ) : maValue( rValue ), mbHasValue( true ) {}
179  explicit OptValue( bool bHasValue, const Type& rValue ) : maValue( rValue ), mbHasValue( bHasValue ) {}
180 
181  bool has() const { return mbHasValue; }
182  bool operator!() const { return !mbHasValue; }
183  bool differsFrom( const Type& rValue ) const { return mbHasValue && (maValue != rValue); }
184 
185  const Type& get() const { return maValue; }
186  const Type& get( const Type& rDefValue ) const { return mbHasValue ? maValue : rDefValue; }
187 
188  void set( const Type& rValue ) { maValue = rValue; mbHasValue = true; }
189  Type& use() { mbHasValue = true; return maValue; }
190 
191  OptValue& operator=( const Type& rValue ) { set( rValue ); return *this; }
192  bool operator==( const OptValue& rValue ) const {
193  return ( ( !mbHasValue && rValue.mbHasValue == false ) ||
194  ( mbHasValue == rValue.mbHasValue && maValue == rValue.maValue ) );
195  }
196  void assignIfUsed( const OptValue& rValue ) { if( rValue.mbHasValue ) set( rValue.maValue ); }
197 
198 private:
201 };
202 
203 
215 {
216 public:
217 #ifdef OSL_BIGENDIAN
218  static void convertLittleEndian( sal_Int8& ) {} // present for usage in templates
219  static void convertLittleEndian( sal_uInt8& ) {} // present for usage in templates
220  static void convertLittleEndian( char16_t& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
221  static void convertLittleEndian( sal_Int16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
222  static void convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
223  static void convertLittleEndian( sal_Int32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
224  static void convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
225  static void convertLittleEndian( sal_Int64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
226  static void convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
227  static void convertLittleEndian( float& rfValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
228  static void convertLittleEndian( double& rfValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
229 
230  template< typename Type >
231  inline static void convertLittleEndianArray( Type* pnArray, size_t nElemCount );
232 
233  static void convertLittleEndianArray( sal_Int8*, size_t ) {}
234  static void convertLittleEndianArray( sal_uInt8*, size_t ) {}
235 
236 #else
237  template< typename Type >
238  static void convertLittleEndian( Type& ) {}
239 
240  template< typename Type >
241  static void convertLittleEndianArray( Type*, size_t ) {}
242 
243 #endif
244 
249  template< typename Type >
250  inline static void writeLittleEndian( void* pDstBuffer, Type nValue );
251 
252 #ifdef OSL_BIGENDIAN
253 private:
254  inline static void swap2( sal_uInt8* pnData );
255  inline static void swap4( sal_uInt8* pnData );
256  inline static void swap8( sal_uInt8* pnData );
257 #endif
258 };
259 
260 
261 template< typename Type >
262 inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue )
263 {
264  convertLittleEndian( nValue );
265  memcpy( pDstBuffer, &nValue, sizeof( Type ) );
266 }
267 
268 #ifdef OSL_BIGENDIAN
269 template< typename Type >
270 inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount )
271 {
272  for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray )
273  convertLittleEndian( *pnArray );
274 }
275 
276 inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
277 {
278  ::std::swap( pnData[ 0 ], pnData[ 1 ] );
279 }
280 
281 inline void ByteOrderConverter::swap4( sal_uInt8* pnData )
282 {
283  ::std::swap( pnData[ 0 ], pnData[ 3 ] );
284  ::std::swap( pnData[ 1 ], pnData[ 2 ] );
285 }
286 
287 inline void ByteOrderConverter::swap8( sal_uInt8* pnData )
288 {
289  ::std::swap( pnData[ 0 ], pnData[ 7 ] );
290  ::std::swap( pnData[ 1 ], pnData[ 6 ] );
291  ::std::swap( pnData[ 2 ], pnData[ 5 ] );
292  ::std::swap( pnData[ 3 ], pnData[ 4 ] );
293 }
294 #endif
295 
296 
297 } // namespace oox
298 
299 #endif
300 
301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Provides platform independent functions to convert from or to little-endian byte order, e.g.
Definition: helper.hxx:214
const sal_Int16 API_LINE_THIN
Definition: helper.hxx:94
Type
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
const sal_Int16 API_LINE_HAIR
Definition: helper.hxx:93
OptValue(const Type &rValue)
Definition: helper.hxx:178
const sal_Int16 API_LINE_SOLID
Definition: helper.hxx:87
signed char sal_Int8
const sal_uInt32 UNSIGNED_RGB_TRANSPARENT
Transparent color for unsigned int32 places.
Definition: helper.hxx:82
const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN
Definition: helper.hxx:63
const sal_Int16 API_LINE_MEDIUM
Definition: helper.hxx:95
bool operator==(const OptValue &rValue) const
Definition: helper.hxx:192
const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE
Definition: helper.hxx:71
const sal_Int16 API_LINE_THICK
Definition: helper.hxx:96
const sal_Int16 API_ESCAPE_SUPERSCRIPT
Superscript: raise characters automatically (magic value 101).
Definition: helper.hxx:99
OptValue(bool bHasValue, const Type &rValue)
Definition: helper.hxx:179
ReturnType extractValue(Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount)
Extracts a value from a bit field.
Definition: helper.hxx:155
const sal_Int16 API_ESCAPE_NONE
No escapement.
Definition: helper.hxx:98
const sal_Int8 API_ESCAPEHEIGHT_NONE
Relative character height if not escaped.
Definition: helper.hxx:102
void set(const Type &rValue)
Definition: helper.hxx:188
const sal_uInt8 WINDOWS_CHARSET_EASTERN
Definition: helper.hxx:77
int nCount
const sal_uInt8 WINDOWS_CHARSET_JOHAB
Definition: helper.hxx:66
const sal_uInt8 WINDOWS_CHARSET_DEFAULT
Definition: helper.hxx:61
const sal_uInt8 WINDOWS_CHARSET_TURKISH
Definition: helper.hxx:70
bool getFlag(Type nBitField, Type nMask)
Returns true, if at least one of the bits set in nMask is set in nBitField.
Definition: helper.hxx:135
void setFlag(Type &ornBitField, Type nMask, bool bSet=true)
Sets or clears (according to bSet) all set bits of nMask in ornBitField.
Definition: helper.hxx:165
const sal_uInt8 WINDOWS_CHARSET_HANGEUL
Definition: helper.hxx:65
const sal_Int16 API_LINE_DASHED
Definition: helper.hxx:89
Type & use()
Definition: helper.hxx:189
const sal_uInt8 WINDOWS_CHARSET_SYMBOL
Definition: helper.hxx:62
void assignIfUsed(const OptValue &rValue)
Definition: helper.hxx:196
const sal_uInt8 WINDOWS_CHARSET_BIG5
Definition: helper.hxx:68
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS
Definition: helper.hxx:64
const sal_Int16 API_LINE_DOTTED
Definition: helper.hxx:88
const sal_Int16 API_ESCAPE_SUBSCRIPT
Subscript: lower characters automatically (magic value -101).
Definition: helper.hxx:100
ReturnType getLimitedValue(Type nValue, Type nMin, Type nMax)
Definition: helper.hxx:109
const ::Color API_RGB_BLACK(0x000000)
Black color for API calls.
static void writeLittleEndian(void *pDstBuffer, Type nValue)
Writes a value to memory, while converting it to little-endian.
Definition: helper.hxx:262
static void convertLittleEndianArray(Type *, size_t)
Definition: helper.hxx:241
const sal_uInt8 WINDOWS_CHARSET_HEBREW
Definition: helper.hxx:72
const sal_Int8 API_ESCAPEHEIGHT_DEFAULT
Relative character height if escaped.
Definition: helper.hxx:103
bool operator!() const
Definition: helper.hxx:182
const sal_uInt8 WINDOWS_CHARSET_THAI
Definition: helper.hxx:76
const sal_uInt8 WINDOWS_CHARSET_RUSSIAN
Definition: helper.hxx:75
bool mbHasValue
Definition: helper.hxx:200
const sal_uInt8 WINDOWS_CHARSET_BALTIC
Definition: helper.hxx:74
unsigned char sal_uInt8
ReturnType getFlagValue(Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset)
Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. ...
Definition: helper.hxx:142
const sal_uInt8 WINDOWS_CHARSET_GB2312
Definition: helper.hxx:67
const sal_uInt8 WINDOWS_CHARSET_ARABIC
Definition: helper.hxx:73
ReturnType getIntervalValue(Type nValue, Type nBegin, Type nEnd)
Definition: helper.hxx:115
const sal_Int16 API_FINE_LINE_DASHED
Definition: helper.hxx:90
Type maValue
Definition: helper.hxx:199
const sal_Int16 API_LINE_NONE
Definition: helper.hxx:92
const sal_uInt8 WINDOWS_CHARSET_OEM
Definition: helper.hxx:78
const sal_uInt8 WINDOWS_CHARSET_GREEK
Definition: helper.hxx:69
const ::Color API_RGB_GRAY(0x808080)
Gray color for API calls.
Optional value, similar to ::std::optional<>, with convenience accessors.
Definition: helper.hxx:174
ReturnType getDoubleIntervalValue(double fValue, double fBegin, double fEnd)
Definition: helper.hxx:124
OptValue & operator=(const Type &rValue)
Definition: helper.hxx:191
bool has() const
Definition: helper.hxx:181
const sal_uInt8 WINDOWS_CHARSET_ANSI
Definition: helper.hxx:60
constexpr std::make_unsigned_t< T > make_unsigned(T value)
Definition: helper.hxx:43
const ::Color API_RGB_WHITE(0xFFFFFF)
White color for API calls.
bool differsFrom(const Type &rValue) const
Definition: helper.hxx:183
static void convertLittleEndian(Type &)
Definition: helper.hxx:238