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#include <optional>
28
29#include <o3tl/safeint.hxx>
30#include <osl/endian.h>
31#include <rtl/math.hxx>
32#include <sal/macros.h>
33#include <sal/types.h>
34#include <tools/color.hxx>
35#include <utility>
36
37namespace oox {
38
39// Helper macros ==============================================================
40
41namespace detail {
42
43//TODO: Temporary helper for STATIC_ARRAY_SELECT; ultimately, the latter should be replaced by a
44// proper function (template):
45template<typename T> constexpr std::make_unsigned_t<T> make_unsigned(T value) {
46 if constexpr (std::is_signed_v<T>) {
48 } else {
49 return value;
50 }
51}
52
53}
54
57#define STATIC_ARRAY_SELECT( array, index, def ) \
58 ((detail::make_unsigned(index) < SAL_N_ELEMENTS(array)) ? ((array)[static_cast<size_t>(index)]) : (def))
59
60// Common constants ===========================================================
61
81
82
83const ::Color API_RGB_TRANSPARENT (ColorTransparency, 0xffffffff);
84const sal_uInt32 UNSIGNED_RGB_TRANSPARENT = static_cast<sal_uInt32>(-1);
85const ::Color API_RGB_BLACK (0x000000);
86const ::Color API_RGB_GRAY (0x808080);
87const ::Color API_RGB_WHITE (0xFFFFFF);
88
89const sal_Int16 API_LINE_SOLID = 0;
90const sal_Int16 API_LINE_DOTTED = 1;
91const sal_Int16 API_LINE_DASHED = 2;
92const sal_Int16 API_FINE_LINE_DASHED = 14;
93
94const sal_Int16 API_LINE_NONE = 0;
95const sal_Int16 API_LINE_HAIR = 2;
96const sal_Int16 API_LINE_THIN = 35;
97const sal_Int16 API_LINE_MEDIUM = 88;
98const sal_Int16 API_LINE_THICK = 141;
99
100const sal_Int16 API_ESCAPE_NONE = 0;
101const sal_Int16 API_ESCAPE_SUPERSCRIPT = 101;
102const sal_Int16 API_ESCAPE_SUBSCRIPT = -101;
103
106
107
108// Limitate values ------------------------------------------------------------
109
110template< typename ReturnType, typename Type >
111inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax )
112{
113 return static_cast< ReturnType >( ::std::clamp( nValue, nMin, nMax ) );
114}
115
116template< typename ReturnType, typename Type >
117inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd )
118{
119 static_assert(::std::numeric_limits< Type >::is_integer, "is integer");
120 Type nInterval = nEnd - nBegin;
121 Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval);
122 return static_cast< ReturnType >( nValue - nCount * nInterval );
123}
124
125template< typename ReturnType >
126inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd )
127{
128 double fInterval = fEnd - fBegin;
129 double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval );
130 return static_cast< ReturnType >( fValue - fCount * fInterval );
131}
132
133// Read from bitfields --------------------------------------------------------
134
136template< typename Type >
137inline bool getFlag( Type nBitField, Type nMask )
138{
139 return (nBitField & nMask) != 0;
140}
141
143template< typename ReturnType, typename Type >
144inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
145{
146 return getFlag( nBitField, nMask ) ? nSet : nUnset;
147}
148
156template< typename ReturnType, typename Type >
157inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
158{
159 sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
160 return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) );
161}
162
163// Write to bitfields ---------------------------------------------------------
164
166template< typename Type >
167inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true )
168{
169 if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask;
170}
171
172
173template< typename Type >
174void assignIfUsed( std::optional<Type>& rDestValue, const std::optional<Type>& rSourceValue )
175{
176 if( rSourceValue.has_value() )
177 rDestValue = rSourceValue.value();
178}
179
180
192{
193public:
194#ifdef OSL_BIGENDIAN
195 static void convertLittleEndian( sal_Int8& ) {} // present for usage in templates
196 static void convertLittleEndian( sal_uInt8& ) {} // present for usage in templates
197 static void convertLittleEndian( char16_t& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
198 static void convertLittleEndian( sal_Int16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
199 static void convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
200 static void convertLittleEndian( sal_Int32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
201 static void convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
202 static void convertLittleEndian( sal_Int64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
203 static void convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
204 static void convertLittleEndian( float& rfValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
205 static void convertLittleEndian( double& rfValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
206
207 template< typename Type >
208 inline static void convertLittleEndianArray( Type* pnArray, size_t nElemCount );
209
210 static void convertLittleEndianArray( sal_Int8*, size_t ) {}
211 static void convertLittleEndianArray( sal_uInt8*, size_t ) {}
212
213#else
214 template< typename Type >
215 static void convertLittleEndian( Type& ) {}
216
217 template< typename Type >
218 static void convertLittleEndianArray( Type*, size_t ) {}
219
220#endif
221
226 template< typename Type >
227 inline static void writeLittleEndian( void* pDstBuffer, Type nValue );
228
229#ifdef OSL_BIGENDIAN
230private:
231 inline static void swap2( sal_uInt8* pnData );
232 inline static void swap4( sal_uInt8* pnData );
233 inline static void swap8( sal_uInt8* pnData );
234#endif
235};
236
237
238template< typename Type >
239inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue )
240{
242 memcpy( pDstBuffer, &nValue, sizeof( Type ) );
243}
244
245#ifdef OSL_BIGENDIAN
246template< typename Type >
247inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount )
248{
249 for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray )
250 convertLittleEndian( *pnArray );
251}
252
253inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
254{
255 ::std::swap( pnData[ 0 ], pnData[ 1 ] );
256}
257
258inline void ByteOrderConverter::swap4( sal_uInt8* pnData )
259{
260 ::std::swap( pnData[ 0 ], pnData[ 3 ] );
261 ::std::swap( pnData[ 1 ], pnData[ 2 ] );
262}
263
264inline void ByteOrderConverter::swap8( sal_uInt8* pnData )
265{
266 ::std::swap( pnData[ 0 ], pnData[ 7 ] );
267 ::std::swap( pnData[ 1 ], pnData[ 6 ] );
268 ::std::swap( pnData[ 2 ], pnData[ 5 ] );
269 ::std::swap( pnData[ 3 ], pnData[ 4 ] );
270}
271#endif
272
273
274} // namespace oox
275
276#endif
277
278/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Provides platform independent functions to convert from or to little-endian byte order,...
Definition: helper.hxx:192
static void convertLittleEndianArray(Type *, size_t)
Definition: helper.hxx:218
static void convertLittleEndian(Type &)
Definition: helper.hxx:215
static void writeLittleEndian(void *pDstBuffer, Type nValue)
Writes a value to memory, while converting it to little-endian.
Definition: helper.hxx:239
Any value
int nCount
sal_Int16 nValue
short nBitCount
Type
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
constexpr std::make_unsigned_t< T > make_unsigned(T value)
Definition: helper.hxx:45
const sal_Int16 API_ESCAPE_SUBSCRIPT
Subscript: lower characters automatically (magic value -101).
Definition: helper.hxx:102
const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE
Definition: helper.hxx:73
void assignIfUsed(std::optional< Type > &rDestValue, const std::optional< Type > &rSourceValue)
Definition: helper.hxx:174
const sal_uInt8 WINDOWS_CHARSET_ANSI
Definition: helper.hxx:62
const sal_Int16 API_LINE_MEDIUM
Definition: helper.hxx:97
const sal_uInt8 WINDOWS_CHARSET_BALTIC
Definition: helper.hxx:76
const sal_uInt32 UNSIGNED_RGB_TRANSPARENT
Transparent color for unsigned int32 places.
Definition: helper.hxx:84
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:144
const sal_Int16 API_ESCAPE_NONE
No escapement.
Definition: helper.hxx:100
const sal_uInt8 WINDOWS_CHARSET_HEBREW
Definition: helper.hxx:74
const sal_uInt8 WINDOWS_CHARSET_GB2312
Definition: helper.hxx:69
const sal_Int16 API_LINE_DOTTED
Definition: helper.hxx:90
const ::Color API_RGB_WHITE(0xFFFFFF)
White color for API calls.
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:167
const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS
Definition: helper.hxx:66
const sal_uInt8 WINDOWS_CHARSET_TURKISH
Definition: helper.hxx:72
const ::Color API_RGB_GRAY(0x808080)
Gray color for API calls.
const sal_Int16 API_LINE_NONE
Definition: helper.hxx:94
const sal_uInt8 WINDOWS_CHARSET_JOHAB
Definition: helper.hxx:68
const sal_Int16 API_LINE_THICK
Definition: helper.hxx:98
const sal_uInt8 WINDOWS_CHARSET_OEM
Definition: helper.hxx:80
const sal_Int16 API_LINE_THIN
Definition: helper.hxx:96
const sal_uInt8 WINDOWS_CHARSET_DEFAULT
Definition: helper.hxx:63
ReturnType getIntervalValue(Type nValue, Type nBegin, Type nEnd)
Definition: helper.hxx:117
const sal_Int16 API_LINE_SOLID
Definition: helper.hxx:89
const ::Color API_RGB_BLACK(0x000000)
Black color for API calls.
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:137
const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN
Definition: helper.hxx:65
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
const sal_uInt8 WINDOWS_CHARSET_HANGEUL
Definition: helper.hxx:67
const sal_uInt8 WINDOWS_CHARSET_ARABIC
Definition: helper.hxx:75
const sal_uInt8 WINDOWS_CHARSET_THAI
Definition: helper.hxx:78
const sal_Int16 API_FINE_LINE_DASHED
Definition: helper.hxx:92
const sal_Int16 API_LINE_DASHED
Definition: helper.hxx:91
const sal_Int8 API_ESCAPEHEIGHT_NONE
Relative character height if not escaped.
Definition: helper.hxx:104
const sal_Int16 API_ESCAPE_SUPERSCRIPT
Superscript: raise characters automatically (magic value 101).
Definition: helper.hxx:101
const sal_Int16 API_LINE_HAIR
Definition: helper.hxx:95
const sal_uInt8 WINDOWS_CHARSET_BIG5
Definition: helper.hxx:70
const sal_uInt8 WINDOWS_CHARSET_SYMBOL
Definition: helper.hxx:64
const sal_uInt8 WINDOWS_CHARSET_GREEK
Definition: helper.hxx:71
ReturnType extractValue(Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount)
Extracts a value from a bit field.
Definition: helper.hxx:157
const sal_uInt8 WINDOWS_CHARSET_EASTERN
Definition: helper.hxx:79
const sal_uInt8 WINDOWS_CHARSET_RUSSIAN
Definition: helper.hxx:77
ReturnType getLimitedValue(Type nValue, Type nMin, Type nMax)
Definition: helper.hxx:111
const sal_Int8 API_ESCAPEHEIGHT_DEFAULT
Relative character height if escaped.
Definition: helper.hxx:105
ReturnType getDoubleIntervalValue(double fValue, double fBegin, double fEnd)
Definition: helper.hxx:126
unsigned char sal_uInt8
signed char sal_Int8