1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* 3 * This file is part of the libetonyek 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 10 #ifndef LIBETONYEK_UTILS_H_INCLUDED 11 #define LIBETONYEK_UTILS_H_INCLUDED 12 13 #ifdef HAVE_CONFIG_H 14 #include "config.h" 15 #endif 16 17 #include <cmath> 18 #include <memory> 19 #include <string> 20 21 #include <boost/cstdint.hpp> 22 23 #include <librevenge/librevenge.h> 24 #include <librevenge-stream/librevenge-stream.h> 25 26 #define ETONYEK_EPSILON 1e-9 27 #define ETONYEK_ALMOST_ZERO(x) (std::fabs(x) < ETONYEK_EPSILON) 28 29 #define ETONYEK_NUM_ELEMENTS(array) (sizeof(array) / sizeof((array)[0])) 30 31 #if defined(HAVE_FUNC_ATTRIBUTE_FORMAT) 32 # define ETONYEK_ATTRIBUTE_PRINTF(fmt, arg) __attribute__((__format__(__printf__, fmt, arg))) 33 #else 34 # define ETONYEK_ATTRIBUTE_PRINTF(fmt, arg) 35 #endif 36 37 #if defined(HAVE_CLANG_ATTRIBUTE_FALLTHROUGH) 38 # define ETONYEK_FALLTHROUGH [[clang::fallthrough]] 39 #elif defined(HAVE_GCC_ATTRIBUTE_FALLTHROUGH) 40 # define ETONYEK_FALLTHROUGH __attribute__((fallthrough)) 41 #else 42 # define ETONYEK_FALLTHROUGH ((void) 0) 43 #endif 44 45 // do nothing with debug messages in a release compile 46 #ifdef DEBUG 47 namespace libetonyek 48 { 49 void debugPrint(const char *format, ...) ETONYEK_ATTRIBUTE_PRINTF(1, 2); 50 } 51 #define ETONYEK_DEBUG_MSG(M) libetonyek::debugPrint M 52 #define ETONYEK_DEBUG(M) M 53 #else 54 #define ETONYEK_DEBUG_MSG(M) 55 #define ETONYEK_DEBUG(M) 56 #endif 57 58 namespace libetonyek 59 { 60 61 struct IWORKColor; 62 struct IWORKGradient; 63 struct IWORKStroke; 64 65 /* Constants */ 66 const double etonyek_half_pi(1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00); 67 const double etonyek_third_pi(1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550e+00); 68 const double etonyek_pi(3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00); 69 const double etonyek_two_pi(6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303e+00); 70 71 const double etonyek_root_three(1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614142e+00); 72 const double etonyek_root_two(1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623e+00); 73 74 // Apple Numbers timestamp starts from 01 Jan 2001 00:00:00 75 const unsigned ETONYEK_EPOCH_BEGIN(978307200); 76 77 struct EtonyekDummyDeleter 78 { operatorEtonyekDummyDeleter79 void operator()(void *) {} 80 }; 81 82 typedef std::shared_ptr<librevenge::RVNGInputStream> RVNGInputStreamPtr_t; 83 84 uint8_t readU8(const RVNGInputStreamPtr_t &input, bool = false); 85 uint16_t readU16(const RVNGInputStreamPtr_t &input, bool bigEndian=false); 86 uint32_t readU32(const RVNGInputStreamPtr_t &input, bool bigEndian=false); 87 uint64_t readU64(const RVNGInputStreamPtr_t &input, bool bigEndian=false); 88 89 uint64_t readUVar(const RVNGInputStreamPtr_t &input); 90 int64_t readSVar(const RVNGInputStreamPtr_t &input); 91 92 double readDouble(const RVNGInputStreamPtr_t &input); 93 float readFloat(const RVNGInputStreamPtr_t &input); 94 95 unsigned long getLength(const RVNGInputStreamPtr_t &input); 96 unsigned long getRemainingLength(const RVNGInputStreamPtr_t &input); 97 98 /** Test two floating point numbers for equality. 99 * 100 * @arg[in] x first number 101 * @arg[in] y second number 102 * @arg[in] eps precision 103 */ 104 bool approxEqual(double x, double y, double eps = ETONYEK_EPSILON); 105 106 template<class T> 107 bool approxEqual(const T &left, const T &right, const double eps = ETONYEK_EPSILON) 108 { 109 assert(left.length() == right.length()); 110 111 for (int i = 0; i != left.length(); ++i) 112 { 113 if (!approxEqual(left[i], right[i], eps)) 114 return false; 115 } 116 return true; 117 } 118 119 /** Convert a length from points to inches. 120 * 121 * @arg[in] d length in points 122 * @returns length in inches 123 */ 124 double pt2in(double d); 125 126 /** Convert an angle from degrees to radians. 127 * 128 * @arg[in] value angle in degrees 129 * @returns the same angle in radians 130 */ 131 double deg2rad(double value); 132 133 /** Convert an angle from radians to degrees. 134 * 135 * @arg[in] value angle in radians 136 * @returns the same angle in degrees 137 */ 138 double rad2deg(double value); 139 140 librevenge::RVNGString makeColor(const IWORKColor &color); 141 /** Compute the average color of a gradient and return it as a string. 142 */ 143 librevenge::RVNGString makeColor(const IWORKGradient &gradient); 144 145 void writeBorder(const IWORKStroke &stroke, const char *name, librevenge::RVNGPropertyList &props); 146 147 std::string detectMimetype(const RVNGInputStreamPtr_t &stream); 148 149 class EndOfStreamException 150 { 151 }; 152 153 class GenericException 154 { 155 }; 156 157 } // namespace libetonyek 158 159 #endif // LIBETONYEK_UTILS_H_INCLUDED 160 161 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */ 162