update emoji autocorrect entries from po-files
[LibreOffice.git] / include / oox / helper / helper.hxx
blobf36e6325ebd985b389b08cf088f9a4d97a62bef3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_OOX_HELPER_HELPER_HXX
21 #define INCLUDED_OOX_HELPER_HELPER_HXX
23 #include <algorithm>
24 #include <limits>
25 #include <sal/macros.h>
26 #include <osl/endian.h>
27 #include <rtl/math.hxx>
28 #include <rtl/string.hxx>
29 #include <rtl/ustring.hxx>
30 #include <string.h>
32 namespace oox {
34 // Helper macros ==============================================================
36 /** Expands to a pointer behind the last element of a STATIC data array (like
37 STL end()). */
38 #define STATIC_ARRAY_END( array ) \
39 ((array)+SAL_N_ELEMENTS(array))
41 /** Expands to the 'index'-th element of a STATIC data array, or to 'def', if
42 'index' is out of the array limits. */
43 #define STATIC_ARRAY_SELECT( array, index, def ) \
44 ((static_cast<size_t>(index) < SAL_N_ELEMENTS(array)) ? ((array)[static_cast<size_t>(index)]) : (def))
46 /** Expands to a temporary OString, created from a literal(!) character
47 array. */
48 #define CREATE_OSTRING( ascii ) \
49 OString( RTL_CONSTASCII_STRINGPARAM( ascii ) )
51 /** Convert an OUString to an ASCII C string. Use for debug purposes only. */
52 #define OUSTRING_TO_CSTR( str ) \
53 OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ).getStr()
55 // Common constants ===========================================================
57 const sal_uInt8 WINDOWS_CHARSET_ANSI = 0;
58 const sal_uInt8 WINDOWS_CHARSET_DEFAULT = 1;
59 const sal_uInt8 WINDOWS_CHARSET_SYMBOL = 2;
60 const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN = 77;
61 const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS = 128;
62 const sal_uInt8 WINDOWS_CHARSET_HANGEUL = 129;
63 const sal_uInt8 WINDOWS_CHARSET_JOHAB = 130;
64 const sal_uInt8 WINDOWS_CHARSET_GB2312 = 134;
65 const sal_uInt8 WINDOWS_CHARSET_BIG5 = 136;
66 const sal_uInt8 WINDOWS_CHARSET_GREEK = 161;
67 const sal_uInt8 WINDOWS_CHARSET_TURKISH = 162;
68 const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE = 163;
69 const sal_uInt8 WINDOWS_CHARSET_HEBREW = 177;
70 const sal_uInt8 WINDOWS_CHARSET_ARABIC = 178;
71 const sal_uInt8 WINDOWS_CHARSET_BALTIC = 186;
72 const sal_uInt8 WINDOWS_CHARSET_RUSSIAN = 204;
73 const sal_uInt8 WINDOWS_CHARSET_THAI = 222;
74 const sal_uInt8 WINDOWS_CHARSET_EASTERN = 238;
75 const sal_uInt8 WINDOWS_CHARSET_OEM = 255;
79 const sal_Int32 API_RGB_TRANSPARENT = -1; ///< Transparent color for API calls.
80 const sal_uInt32 UNSIGNED_RGB_TRANSPARENT = static_cast<sal_uInt32>(-1); ///< Transparent color for unsigned int32 places.
81 const sal_Int32 API_RGB_BLACK = 0x000000; ///< Black color for API calls.
82 const sal_Int32 API_RGB_GRAY = 0x808080; ///< Gray color for API calls.
83 const sal_Int32 API_RGB_WHITE = 0xFFFFFF; ///< White color for API calls.
85 const sal_Int16 API_LINE_SOLID = 0;
86 const sal_Int16 API_LINE_DOTTED = 1;
87 const sal_Int16 API_LINE_DASHED = 2;
88 const sal_Int16 API_FINE_LINE_DASHED = 14;
90 const sal_Int16 API_LINE_NONE = 0;
91 const sal_Int16 API_LINE_HAIR = 2;
92 const sal_Int16 API_LINE_THIN = 35;
93 const sal_Int16 API_LINE_MEDIUM = 88;
94 const sal_Int16 API_LINE_THICK = 141;
96 const sal_Int16 API_ESCAPE_NONE = 0; ///< No escapement.
97 const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101; ///< Superscript: raise characters automatically (magic value 101).
98 const sal_Int16 API_ESCAPE_SUBSCRIPT = -101; ///< Subscript: lower characters automatically (magic value -101).
100 const sal_Int8 API_ESCAPEHEIGHT_NONE = 100; ///< Relative character height if not escaped.
101 const sal_Int8 API_ESCAPEHEIGHT_DEFAULT = 58; ///< Relative character height if escaped.
105 // Limitate values ------------------------------------------------------------
107 template< typename ReturnType, typename Type >
108 inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax )
110 return static_cast< ReturnType >( ::std::min( ::std::max( nValue, nMin ), nMax ) );
113 template< typename ReturnType, typename Type >
114 inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd )
116 static_assert(::std::numeric_limits< Type >::is_integer, "is integer");
117 Type nInterval = nEnd - nBegin;
118 Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval);
119 return static_cast< ReturnType >( nValue - nCount * nInterval );
122 template< typename ReturnType >
123 inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd )
125 double fInterval = fEnd - fBegin;
126 double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval );
127 return static_cast< ReturnType >( fValue - fCount * fInterval );
130 // Read from bitfields --------------------------------------------------------
132 /** Returns true, if at least one of the bits set in nMask is set in nBitField. */
133 template< typename Type >
134 inline bool getFlag( Type nBitField, Type nMask )
136 return (nBitField & nMask) != 0;
139 /** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */
140 template< typename ReturnType, typename Type >
141 inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
143 return getFlag( nBitField, nMask ) ? nSet : nUnset;
146 /** Extracts a value from a bit field.
148 Returns the data fragment from nBitField, that starts at bit nStartBit
149 (0-based, bit 0 is rightmost) with the width of nBitCount. The returned
150 value will be right-aligned (normalized).
151 For instance: extractValue<T>(0x4321,8,4) returns 3 (value in bits 8-11).
153 template< typename ReturnType, typename Type >
154 inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
156 sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
157 return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) );
160 // Write to bitfields ---------------------------------------------------------
162 /** Sets or clears (according to bSet) all set bits of nMask in ornBitField. */
163 template< typename Type >
164 inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true )
166 if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask;
169 /** Inserts a value into a bitfield.
171 Inserts the lower nBitCount bits of nValue into ornBitField, starting
172 there at bit nStartBit. Other contents of ornBitField keep unchanged.
174 template< typename Type, typename InsertType >
175 void insertValue( Type& ornBitField, InsertType nValue, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
177 sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
178 Type nNewValue = static_cast< Type >( nValue & nMask );
179 (ornBitField &= ~(nMask << nStartBit)) |= (nNewValue << nStartBit);
184 /** Optional value, similar to ::boost::optional<>, with convenience accessors.
186 template< typename Type >
187 class OptValue
189 public:
190 OptValue() : maValue(), mbHasValue( false ) {}
191 explicit OptValue( const Type& rValue ) : maValue( rValue ), mbHasValue( true ) {}
192 explicit OptValue( bool bHasValue, const Type& rValue ) : maValue( rValue ), mbHasValue( bHasValue ) {}
194 bool has() const { return mbHasValue; }
195 bool operator!() const { return !mbHasValue; }
196 bool differsFrom( const Type& rValue ) const { return mbHasValue && (maValue != rValue); }
198 const Type& get() const { return maValue; }
199 const Type& get( const Type& rDefValue ) const { return mbHasValue ? maValue : rDefValue; }
201 void reset() { mbHasValue = false; }
202 void set( const Type& rValue ) { maValue = rValue; mbHasValue = true; }
203 Type& use() { mbHasValue = true; return maValue; }
205 OptValue& operator=( const Type& rValue ) { set( rValue ); return *this; }
206 bool operator==( const OptValue& rValue ) const {
207 return ( ( !mbHasValue && rValue.mbHasValue == false ) ||
208 ( mbHasValue == rValue.mbHasValue && maValue == rValue.maValue ) );
210 void assignIfUsed( const OptValue& rValue ) { if( rValue.mbHasValue ) set( rValue.maValue ); }
212 private:
213 Type maValue;
214 bool mbHasValue;
219 /** Provides platform independent functions to convert from or to little-endian
220 byte order, e.g. for reading data from or writing data to memory or a
221 binary stream.
223 On big-endian platforms, the byte order in the passed values is swapped,
224 this can be used for converting big-endian to and from little-endian data.
226 On little-endian platforms, the conversion functions are implemented empty,
227 thus compilers should completely optimize away the function call.
229 class ByteOrderConverter
231 public:
232 #ifdef OSL_BIGENDIAN
233 static void convertLittleEndian( sal_Int8& ) {} // present for usage in templates
234 static void convertLittleEndian( sal_uInt8& ) {} // present for usage in templates
235 static void convertLittleEndian( sal_Int16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
236 static void convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
237 static void convertLittleEndian( sal_Int32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
238 static void convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
239 static void convertLittleEndian( sal_Int64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
240 static void convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
241 static void convertLittleEndian( float& rfValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
242 static void convertLittleEndian( double& rfValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
244 template< typename Type >
245 inline static void convertLittleEndianArray( Type* pnArray, size_t nElemCount );
247 static void convertLittleEndianArray( sal_Int8*, size_t ) {}
248 static void convertLittleEndianArray( sal_uInt8*, size_t ) {}
250 #else
251 template< typename Type >
252 static void convertLittleEndian( Type& ) {}
254 template< typename Type >
255 static void convertLittleEndianArray( Type*, size_t ) {}
257 #endif
259 /** Reads a value from memory, assuming memory buffer in little-endian.
260 @param ornValue (out-parameter) Contains the value read from memory.
261 @param pSrcBuffer The memory buffer to read the value from.
263 template< typename Type >
264 inline static void readLittleEndian( Type& ornValue, const void* pSrcBuffer );
266 /** Writes a value to memory, while converting it to little-endian.
267 @param pDstBuffer The memory buffer to write the value to.
268 @param nValue The value to be written to memory in little-endian.
270 template< typename Type >
271 inline static void writeLittleEndian( void* pDstBuffer, Type nValue );
273 #ifdef OSL_BIGENDIAN
274 private:
275 inline static void swap2( sal_uInt8* pnData );
276 inline static void swap4( sal_uInt8* pnData );
277 inline static void swap8( sal_uInt8* pnData );
278 #endif
283 template< typename Type >
284 inline void ByteOrderConverter::readLittleEndian( Type& ornValue, const void* pSrcBuffer )
286 memcpy( &ornValue, pSrcBuffer, sizeof( Type ) );
287 convertLittleEndian( ornValue );
290 template< typename Type >
291 inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue )
293 convertLittleEndian( nValue );
294 memcpy( pDstBuffer, &nValue, sizeof( Type ) );
297 #ifdef OSL_BIGENDIAN
298 template< typename Type >
299 inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount )
301 for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray )
302 convertLittleEndian( *pnArray );
305 inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
307 ::std::swap( pnData[ 0 ], pnData[ 1 ] );
310 inline void ByteOrderConverter::swap4( sal_uInt8* pnData )
312 ::std::swap( pnData[ 0 ], pnData[ 3 ] );
313 ::std::swap( pnData[ 1 ], pnData[ 2 ] );
316 inline void ByteOrderConverter::swap8( sal_uInt8* pnData )
318 ::std::swap( pnData[ 0 ], pnData[ 7 ] );
319 ::std::swap( pnData[ 1 ], pnData[ 6 ] );
320 ::std::swap( pnData[ 2 ], pnData[ 5 ] );
321 ::std::swap( pnData[ 3 ], pnData[ 4 ] );
323 #endif
327 } // namespace oox
329 #endif
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */