Compare commits

..
Author SHA1 Message Date
Automatic Release Builder 235e38b69b new version: 2016.4.4 2016-12-28 13:57:44 +01:00
James Turner 279b2c120f Bugfix: reject dubious paths in HTTP repos.
This avoids a malicious repository writing to files outside the local
storage root.
(cherry picked from commit a2b111bb09)
2016-12-22 16:59:45 +01:00
Automatic Release Builder c92a953511 new version: 2016.4.3 2016-12-05 13:28:25 +01:00
James Turner 863ae19d1d Package::indexOfvariant works on fully-qualified IDs.
Should fix issues restoring variants in the launcher.
2016-11-29 15:44:19 +00:00
Automatic Release Builder cd7b6d69b0 new version: 2016.4.2 2016-11-22 09:38:58 +01:00
534 changed files with 16098 additions and 48780 deletions
-3
View File
@@ -14,6 +14,3 @@ CTestTestfile.cmake
install_manifest.txt install_manifest.txt
build* build*
Build Build
CMakeLists.txt.user
3rdparty/expat_2.2.6/
nbproject
+2
View File
@@ -2,6 +2,8 @@ if (NOT SYSTEM_EXPAT)
add_subdirectory(expat) add_subdirectory(expat)
endif() endif()
add_subdirectory(utf8)
if (ENABLE_DNS AND NOT SYSTEM_UDNS) if (ENABLE_DNS AND NOT SYSTEM_UDNS)
add_subdirectory(udns) add_subdirectory(udns)
endif() endif()
+1 -1
View File
@@ -1,7 +1,7 @@
configure_file ( configure_file (
"${PROJECT_SOURCE_DIR}/3rdparty/expat/expat_config_cmake.in" "${PROJECT_SOURCE_DIR}/3rdparty/expat/expat_config_cmake.in"
"${PROJECT_BINARY_DIR}/3rdparty/expat/simgear_expat_config.h" "${PROJECT_BINARY_DIR}/3rdparty/expat/expat_config.h"
) )
set(expat_sources set(expat_sources
-2
View File
@@ -18,8 +18,6 @@
#include "amigaconfig.h" #include "amigaconfig.h"
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
#include "watcomconfig.h" #include "watcomconfig.h"
#elif defined(HAVE_SIMGEAR_EXPAT_CONFIG_H)
#include "simgear_expat_config.h"
#elif defined(HAVE_EXPAT_CONFIG_H) #elif defined(HAVE_EXPAT_CONFIG_H)
#include "expat_config.h" #include "expat_config.h"
#endif /* ndef COMPILED_FROM_DSP */ #endif /* ndef COMPILED_FROM_DSP */
-2
View File
@@ -12,8 +12,6 @@
#include "amigaconfig.h" #include "amigaconfig.h"
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
#include "watcomconfig.h" #include "watcomconfig.h"
#elif defined(HAVE_SIMGEAR_EXPAT_CONFIG_H)
#include "simgear_expat_config.h"
#else #else
#ifdef HAVE_EXPAT_CONFIG_H #ifdef HAVE_EXPAT_CONFIG_H
#include "expat_config.h" #include "expat_config.h"
-2
View File
@@ -12,8 +12,6 @@
#include "amigaconfig.h" #include "amigaconfig.h"
#elif defined(__WATCOMC__) #elif defined(__WATCOMC__)
#include "watcomconfig.h" #include "watcomconfig.h"
#elif defined(HAVE_SIMGEAR_EXPAT_CONFIG_H)
#include "simgear_expat_config.h"
#else #else
#ifdef HAVE_EXPAT_CONFIG_H #ifdef HAVE_EXPAT_CONFIG_H
#include "expat_config.h" #include "expat_config.h"
+3 -3
View File
@@ -24,7 +24,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif #endif
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
# include <winsock2.h> /* includes <windows.h> */ # include <winsock2.h> /* includes <windows.h> */
# include <iphlpapi.h> /* for dns server addresses etc */ # include <iphlpapi.h> /* for dns server addresses etc */
#else #else
@@ -53,7 +53,7 @@ static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) {
dns_add_srch(ctx, srch); dns_add_srch(ctx, srch);
} }
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
#ifndef NO_IPHLPAPI #ifndef NO_IPHLPAPI
/* Apparently, some systems does not have proper headers for IPHLPAIP to work. /* Apparently, some systems does not have proper headers for IPHLPAIP to work.
@@ -217,7 +217,7 @@ int dns_init(struct dns_ctx *ctx, int do_open) {
ctx = &dns_defctx; ctx = &dns_defctx;
dns_reset(ctx); dns_reset(ctx);
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
if (dns_initns_iphlpapi(ctx) != 0) if (dns_initns_iphlpapi(ctx) != 0)
dns_initns_registry(ctx); dns_initns_registry(ctx);
/*XXX WINDOWS: probably good to get default domain and search list too... /*XXX WINDOWS: probably good to get default domain and search list too...
+4 -4
View File
@@ -24,7 +24,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif #endif
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
# include <winsock2.h> /* includes <windows.h> */ # include <winsock2.h> /* includes <windows.h> */
# include <ws2tcpip.h> /* needed for struct in6_addr */ # include <ws2tcpip.h> /* needed for struct in6_addr */
#else #else
@@ -392,7 +392,7 @@ dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data) {
} }
static unsigned dns_nonrandom_32(void) { static unsigned dns_nonrandom_32(void) {
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
FILETIME ft; FILETIME ft;
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
return ft.dwLowDateTime; return ft.dwLowDateTime;
@@ -551,7 +551,7 @@ int dns_open(struct dns_ctx *ctx) {
ctx->dnsc_qstatus = DNS_E_TEMPFAIL; ctx->dnsc_qstatus = DNS_E_TEMPFAIL;
return -1; return -1;
} }
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
{ unsigned long on = 1; { unsigned long on = 1;
if (ioctlsocket(sock, FIONBIO, &on) == SOCKET_ERROR) { if (ioctlsocket(sock, FIONBIO, &on) == SOCKET_ERROR) {
closesocket(sock); closesocket(sock);
@@ -991,7 +991,7 @@ again: /* receive the reply */
* or remote. On local errors, we should stop, while * or remote. On local errors, we should stop, while
* remote errors should be ignored (for now anyway). * remote errors should be ignored (for now anyway).
*/ */
#if defined(_WINDOWS) || defined(WINDOWS) #ifdef WINDOWS
if (WSAGetLastError() == WSAEWOULDBLOCK) if (WSAGetLastError() == WSAEWOULDBLOCK)
#else #else
if (errno == EAGAIN) if (errno == EAGAIN)
+1 -1
View File
@@ -27,7 +27,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#if !defined(_WINDOWS) && !defined(WINDOWS) #ifndef WINDOWS
# include <sys/types.h> # include <sys/types.h>
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif
+17
View File
@@ -0,0 +1,17 @@
include (SimGearComponent)
set(HEADERS
source/utf8.h
)
set(HEADERS_utf8
source/utf8/checked.h
source/utf8/core.h
source/utf8/unchecked.h
)
set(SOURCES
)
simgear_component(utf8 3rdparty/utf8 "${SOURCES}" "${HEADERS}")
simgear_component(utf8-internal 3rdparty/utf8/utf8 "" "${HEADERS_utf8}")
+12
View File
@@ -0,0 +1,12 @@
utf8 cpp library
Release 2.3.4
A minor bug fix release. Thanks to all who reported bugs.
Note: Version 2.3.3 contained a regression, and therefore was removed.
Changes from version 2.3.2
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
- Bug fix [36]: replace_invalid() only works with back_inserter
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
+1789
View File
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "utf8/checked.h"
#include "utf8/unchecked.h"
#endif // header guard
+327
View File
@@ -0,0 +1,327 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "core.h"
#include <stdexcept>
namespace utf8
{
// Base for the exceptions that may be thrown from the library
class exception : public ::std::exception {
};
// Exceptions that may be thrown from the library functions.
class invalid_code_point : public exception {
uint32_t cp;
public:
invalid_code_point(uint32_t cp) : cp(cp) {}
virtual const char* what() const throw() { return "Invalid code point"; }
uint32_t code_point() const {return cp;}
};
class invalid_utf8 : public exception {
uint8_t u8;
public:
invalid_utf8 (uint8_t u) : u8(u) {}
virtual const char* what() const throw() { return "Invalid UTF-8"; }
uint8_t utf8_octet() const {return u8;}
};
class invalid_utf16 : public exception {
uint16_t u16;
public:
invalid_utf16 (uint16_t u) : u16(u) {}
virtual const char* what() const throw() { return "Invalid UTF-16"; }
uint16_t utf16_word() const {return u16;}
};
class not_enough_room : public exception {
public:
virtual const char* what() const throw() { return "Not enough space"; }
};
/// The library API - functions intended to be called by the users
template <typename octet_iterator>
octet_iterator append(uint32_t cp, octet_iterator result)
{
if (!utf8::internal::is_code_point_valid(cp))
throw invalid_code_point(cp);
if (cp < 0x80) // one octet
*(result++) = static_cast<uint8_t>(cp);
else if (cp < 0x800) { // two octets
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else if (cp < 0x10000) { // three octets
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else { // four octets
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
return result;
}
template <typename octet_iterator, typename output_iterator>
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
{
while (start != end) {
octet_iterator sequence_start = start;
internal::utf_error err_code = utf8::internal::validate_next(start, end);
switch (err_code) {
case internal::UTF8_OK :
for (octet_iterator it = sequence_start; it != start; ++it)
*out++ = *it;
break;
case internal::NOT_ENOUGH_ROOM:
throw not_enough_room();
case internal::INVALID_LEAD:
out = utf8::append (replacement, out);
++start;
break;
case internal::INCOMPLETE_SEQUENCE:
case internal::OVERLONG_SEQUENCE:
case internal::INVALID_CODE_POINT:
out = utf8::append (replacement, out);
++start;
// just one replacement mark for the sequence
while (start != end && utf8::internal::is_trail(*start))
++start;
break;
}
}
return out;
}
template <typename octet_iterator, typename output_iterator>
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
{
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
return utf8::replace_invalid(start, end, out, replacement_marker);
}
template <typename octet_iterator>
uint32_t next(octet_iterator& it, octet_iterator end)
{
uint32_t cp = 0;
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
switch (err_code) {
case internal::UTF8_OK :
break;
case internal::NOT_ENOUGH_ROOM :
throw not_enough_room();
case internal::INVALID_LEAD :
case internal::INCOMPLETE_SEQUENCE :
case internal::OVERLONG_SEQUENCE :
throw invalid_utf8(*it);
case internal::INVALID_CODE_POINT :
throw invalid_code_point(cp);
}
return cp;
}
template <typename octet_iterator>
uint32_t peek_next(octet_iterator it, octet_iterator end)
{
return utf8::next(it, end);
}
template <typename octet_iterator>
uint32_t prior(octet_iterator& it, octet_iterator start)
{
// can't do much if it == start
if (it == start)
throw not_enough_room();
octet_iterator end = it;
// Go back until we hit either a lead octet or start
while (utf8::internal::is_trail(*(--it)))
if (it == start)
throw invalid_utf8(*it); // error - no lead byte in the sequence
return utf8::peek_next(it, end);
}
/// Deprecated in versions that include "prior"
template <typename octet_iterator>
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
{
octet_iterator end = it;
while (utf8::internal::is_trail(*(--it)))
if (it == pass_start)
throw invalid_utf8(*it); // error - no lead byte in the sequence
octet_iterator temp = it;
return utf8::next(temp, end);
}
template <typename octet_iterator, typename distance_type>
void advance (octet_iterator& it, distance_type n, octet_iterator end)
{
for (distance_type i = 0; i < n; ++i)
utf8::next(it, end);
}
template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
{
typename std::iterator_traits<octet_iterator>::difference_type dist;
for (dist = 0; first < last; ++dist)
utf8::next(first, last);
return dist;
}
template <typename u16bit_iterator, typename octet_iterator>
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
{
while (start != end) {
uint32_t cp = utf8::internal::mask16(*start++);
// Take care of surrogate pairs first
if (utf8::internal::is_lead_surrogate(cp)) {
if (start != end) {
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
if (utf8::internal::is_trail_surrogate(trail_surrogate))
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
else
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
}
else
throw invalid_utf16(static_cast<uint16_t>(cp));
}
// Lone trail surrogate
else if (utf8::internal::is_trail_surrogate(cp))
throw invalid_utf16(static_cast<uint16_t>(cp));
result = utf8::append(cp, result);
}
return result;
}
template <typename u16bit_iterator, typename octet_iterator>
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
{
while (start != end) {
uint32_t cp = utf8::next(start, end);
if (cp > 0xffff) { //make a surrogate pair
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
}
else
*result++ = static_cast<uint16_t>(cp);
}
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
{
while (start != end)
result = utf8::append(*(start++), result);
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
{
while (start != end)
(*result++) = utf8::next(start, end);
return result;
}
// The iterator class
template <typename octet_iterator>
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
octet_iterator it;
octet_iterator range_start;
octet_iterator range_end;
public:
iterator () {}
explicit iterator (const octet_iterator& octet_it,
const octet_iterator& range_start,
const octet_iterator& range_end) :
it(octet_it), range_start(range_start), range_end(range_end)
{
if (it < range_start || it > range_end)
throw std::out_of_range("Invalid utf-8 iterator position");
}
// the default "big three" are OK
octet_iterator base () const { return it; }
uint32_t operator * () const
{
octet_iterator temp = it;
return utf8::next(temp, range_end);
}
bool operator == (const iterator& rhs) const
{
if (range_start != rhs.range_start || range_end != rhs.range_end)
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
return (it == rhs.it);
}
bool operator != (const iterator& rhs) const
{
return !(operator == (rhs));
}
iterator& operator ++ ()
{
utf8::next(it, range_end);
return *this;
}
iterator operator ++ (int)
{
iterator temp = *this;
utf8::next(it, range_end);
return temp;
}
iterator& operator -- ()
{
utf8::prior(it, range_start);
return *this;
}
iterator operator -- (int)
{
iterator temp = *this;
utf8::prior(it, range_start);
return temp;
}
}; // class iterator
} // namespace utf8
#endif //header guard
+329
View File
@@ -0,0 +1,329 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include <iterator>
namespace utf8
{
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
// You may need to change them to match your system.
// These typedefs have the same names as ones from cstdint, or boost/cstdint
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
// Helper code - not intended to be directly called by the library users. May be changed at any time
namespace internal
{
// Unicode constants
// Leading (high) surrogates: 0xd800 - 0xdbff
// Trailing (low) surrogates: 0xdc00 - 0xdfff
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
// Maximum valid value for a Unicode code point
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
template<typename octet_type>
inline uint8_t mask8(octet_type oc)
{
return static_cast<uint8_t>(0xff & oc);
}
template<typename u16_type>
inline uint16_t mask16(u16_type oc)
{
return static_cast<uint16_t>(0xffff & oc);
}
template<typename octet_type>
inline bool is_trail(octet_type oc)
{
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
}
template <typename u16>
inline bool is_lead_surrogate(u16 cp)
{
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
}
template <typename u16>
inline bool is_trail_surrogate(u16 cp)
{
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
}
template <typename u16>
inline bool is_surrogate(u16 cp)
{
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
}
template <typename u32>
inline bool is_code_point_valid(u32 cp)
{
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
}
template <typename octet_iterator>
inline typename std::iterator_traits<octet_iterator>::difference_type
sequence_length(octet_iterator lead_it)
{
uint8_t lead = utf8::internal::mask8(*lead_it);
if (lead < 0x80)
return 1;
else if ((lead >> 5) == 0x6)
return 2;
else if ((lead >> 4) == 0xe)
return 3;
else if ((lead >> 3) == 0x1e)
return 4;
else
return 0;
}
template <typename octet_difference_type>
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
{
if (cp < 0x80) {
if (length != 1)
return true;
}
else if (cp < 0x800) {
if (length != 2)
return true;
}
else if (cp < 0x10000) {
if (length != 3)
return true;
}
return false;
}
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
/// Helper for get_sequence_x
template <typename octet_iterator>
utf_error increase_safely(octet_iterator& it, octet_iterator end)
{
if (++it == end)
return NOT_ENOUGH_ROOM;
if (!utf8::internal::is_trail(*it))
return INCOMPLETE_SEQUENCE;
return UTF8_OK;
}
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
/// get_sequence_x functions decode utf-8 sequences of the length x
template <typename octet_iterator>
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (*it) & 0x3f;
return UTF8_OK;
}
template <typename octet_iterator>
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
if (it == end)
return NOT_ENOUGH_ROOM;
code_point = utf8::internal::mask8(*it);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
code_point += (*it) & 0x3f;
return UTF8_OK;
}
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
template <typename octet_iterator>
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
{
// Save the original value of it so we can go back in case of failure
// Of course, it does not make much sense with i.e. stream iterators
octet_iterator original_it = it;
uint32_t cp = 0;
// Determine the sequence length based on the lead octet
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
const octet_difference_type length = utf8::internal::sequence_length(it);
// Get trail octets and calculate the code point
utf_error err = UTF8_OK;
switch (length) {
case 0:
return INVALID_LEAD;
case 1:
err = utf8::internal::get_sequence_1(it, end, cp);
break;
case 2:
err = utf8::internal::get_sequence_2(it, end, cp);
break;
case 3:
err = utf8::internal::get_sequence_3(it, end, cp);
break;
case 4:
err = utf8::internal::get_sequence_4(it, end, cp);
break;
}
if (err == UTF8_OK) {
// Decoding succeeded. Now, security checks...
if (utf8::internal::is_code_point_valid(cp)) {
if (!utf8::internal::is_overlong_sequence(cp, length)){
// Passed! Return here.
code_point = cp;
++it;
return UTF8_OK;
}
else
err = OVERLONG_SEQUENCE;
}
else
err = INVALID_CODE_POINT;
}
// Failure branch - restore the original value of the iterator
it = original_it;
return err;
}
template <typename octet_iterator>
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
uint32_t ignored;
return utf8::internal::validate_next(it, end, ignored);
}
} // namespace internal
/// The library API - functions intended to be called by the users
// Byte order mark
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
template <typename octet_iterator>
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
{
octet_iterator result = start;
while (result != end) {
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
if (err_code != internal::UTF8_OK)
return result;
}
return result;
}
template <typename octet_iterator>
inline bool is_valid(octet_iterator start, octet_iterator end)
{
return (utf8::find_invalid(start, end) == end);
}
template <typename octet_iterator>
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
{
return (
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
);
}
//Deprecated in release 2.3
template <typename octet_iterator>
inline bool is_bom (octet_iterator it)
{
return (
(utf8::internal::mask8(*it++)) == bom[0] &&
(utf8::internal::mask8(*it++)) == bom[1] &&
(utf8::internal::mask8(*it)) == bom[2]
);
}
} // namespace utf8
#endif // header guard
+228
View File
@@ -0,0 +1,228 @@
// Copyright 2006 Nemanja Trifunovic
/*
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
#include "core.h"
namespace utf8
{
namespace unchecked
{
template <typename octet_iterator>
octet_iterator append(uint32_t cp, octet_iterator result)
{
if (cp < 0x80) // one octet
*(result++) = static_cast<uint8_t>(cp);
else if (cp < 0x800) { // two octets
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else if (cp < 0x10000) { // three octets
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
else { // four octets
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
}
return result;
}
template <typename octet_iterator>
uint32_t next(octet_iterator& it)
{
uint32_t cp = utf8::internal::mask8(*it);
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
switch (length) {
case 1:
break;
case 2:
it++;
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
break;
case 3:
++it;
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
++it;
cp += (*it) & 0x3f;
break;
case 4:
++it;
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
++it;
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
++it;
cp += (*it) & 0x3f;
break;
}
++it;
return cp;
}
template <typename octet_iterator>
uint32_t peek_next(octet_iterator it)
{
return utf8::unchecked::next(it);
}
template <typename octet_iterator>
uint32_t prior(octet_iterator& it)
{
while (utf8::internal::is_trail(*(--it))) ;
octet_iterator temp = it;
return utf8::unchecked::next(temp);
}
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
template <typename octet_iterator>
inline uint32_t previous(octet_iterator& it)
{
return utf8::unchecked::prior(it);
}
template <typename octet_iterator, typename distance_type>
void advance (octet_iterator& it, distance_type n)
{
for (distance_type i = 0; i < n; ++i)
utf8::unchecked::next(it);
}
template <typename octet_iterator>
typename std::iterator_traits<octet_iterator>::difference_type
distance (octet_iterator first, octet_iterator last)
{
typename std::iterator_traits<octet_iterator>::difference_type dist;
for (dist = 0; first < last; ++dist)
utf8::unchecked::next(first);
return dist;
}
template <typename u16bit_iterator, typename octet_iterator>
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
{
while (start != end) {
uint32_t cp = utf8::internal::mask16(*start++);
// Take care of surrogate pairs first
if (utf8::internal::is_lead_surrogate(cp)) {
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
}
result = utf8::unchecked::append(cp, result);
}
return result;
}
template <typename u16bit_iterator, typename octet_iterator>
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
{
while (start < end) {
uint32_t cp = utf8::unchecked::next(start);
if (cp > 0xffff) { //make a surrogate pair
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
}
else
*result++ = static_cast<uint16_t>(cp);
}
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
{
while (start != end)
result = utf8::unchecked::append(*(start++), result);
return result;
}
template <typename octet_iterator, typename u32bit_iterator>
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
{
while (start < end)
(*result++) = utf8::unchecked::next(start);
return result;
}
// The iterator class
template <typename octet_iterator>
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
octet_iterator it;
public:
iterator () {}
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
// the default "big three" are OK
octet_iterator base () const { return it; }
uint32_t operator * () const
{
octet_iterator temp = it;
return utf8::unchecked::next(temp);
}
bool operator == (const iterator& rhs) const
{
return (it == rhs.it);
}
bool operator != (const iterator& rhs) const
{
return !(operator == (rhs));
}
iterator& operator ++ ()
{
::std::advance(it, utf8::internal::sequence_length(it));
return *this;
}
iterator operator ++ (int)
{
iterator temp = *this;
::std::advance(it, utf8::internal::sequence_length(it));
return temp;
}
iterator& operator -- ()
{
utf8::unchecked::prior(it);
return *this;
}
iterator operator -- (int)
{
iterator temp = *this;
utf8::unchecked::prior(it);
return temp;
}
}; // class iterator
} // namespace utf8::unchecked
} // namespace utf8
#endif // header guard
+42 -192
View File
@@ -7,29 +7,6 @@ if(COMMAND cmake_policy)
if(POLICY CMP0042) if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW) cmake_policy(SET CMP0042 NEW)
endif() endif()
if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
# OpenGL VND policy : use the old definition for now, until we can audit this
if(POLICY CMP0072)
cmake_policy(SET CMP0072 OLD)
endif()
if(POLICY CMP0093)
cmake_policy(SET CMP0093 NEW)
endif()
endif()
message(STATUS "CMAKE Build type: ${CMAKE_BUILD_TYPE}")
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif() endif()
include (CheckFunctionExists) include (CheckFunctionExists)
@@ -41,7 +18,6 @@ include (GenerateExportHeader)
# only relevant for building shared libs but let's set it regardless # only relevant for building shared libs but let's set it regardless
set(CMAKE_OSX_RPATH 1) set(CMAKE_OSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
# let's use & require C++11 - note these are only functional with CMake 3.1 # let's use & require C++11 - note these are only functional with CMake 3.1
# we do manual fallbacks for CMake 3.0 in the compilers section # we do manual fallbacks for CMake 3.0 in the compilers section
@@ -49,15 +25,20 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_STANDARD_REQUIRED YES)
# read 'version' file into a variable (stripping any newlines or spaces) # read 'version' file into a variable (stripping any newlines or spaces)
file(READ simgear-version versionFile) file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION) string(STRIP ${versionFile} SIMGEAR_VERSION)
project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX) project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX)
# add a dependency on the version file # using 10.7 because boost requires libc++ and 10.6 doesn't include it
# Cmake documentation says we must set this before calling project(), but
# it only seems to be picked up setting it /after/ the call to project()
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7")
# add a dependency on the versino file
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) set(FIND_LIBRARY_USE_LIB64_PATHS ON)
# use simgear version also as the SO version (if building SOs) # use simgear version also as the SO version (if building SOs)
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION}) SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
@@ -128,39 +109,18 @@ endif()
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF) option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF) option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
option(ENABLE_GDAL "Set to ON to build SimGear with GDAL support" OFF)
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON) option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON) option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON)
option(USE_AEONWAVE "Set to ON to use AeonWave instead of OpenAL" ON) option(USE_AEONWAVE "Set to ON to use AeonWave instead of OpenAL" OFF)
option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON) option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON)
option(ENABLE_DNS "Set to ON to use udns library and DNS service resolver" ON) option(ENABLE_DNS "Set to ON to use udns library and DNS service resolver" ON)
option(ENABLE_SIMD "Enable SSE/SSE2 support for compilers" ON)
option(ENABLE_SIMD_CODE "Enable SSE/SSE2 support code for compilers" OFF)
option(ENABLE_OPENMP "Enable OpenMP compiler support" OFF)
if (NOT ENABLE_SIMD AND ENABLE_SIMD_CODE)
set(ENABLE_SIMD_CODE OFF)
endif()
include (DetectArch)
include (ExportDebugSymbols)
# until the fstream fix is applied and generally available in OSG, # until the fstream fix is applied and generally available in OSG,
# keep the compatability link option as the default # keep the compatability link option as the default
option(OSG_FSTREAM_EXPORT_FIXED "Set to ON if the osgDB fstream export patch is applied" OFF) option(OSG_FSTREAM_EXPORT_FIXED "Set to ON if the osgDB fstream export patch is applied" OFF)
if (CMAKE_COMPILER_IS_GNUCXX OR CLANG)
if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
elseif (CMAKE_VERSION VERSION_LESS 3.8)
# policy CMP0067 (try_compile does not honor CMAKE_CXX_STANDARD)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++${CMAKE_CXX_STANDARD}")
endif()
endif()
if (MSVC) if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} DIRECTORY) GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
if (CMAKE_CL_64) if (CMAKE_CL_64)
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64") SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
else (CMAKE_CL_64) else (CMAKE_CL_64)
@@ -171,11 +131,6 @@ if (MSVC)
else (EXISTS ${TEST_3RDPARTY_DIR}) else (EXISTS ${TEST_3RDPARTY_DIR})
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted") set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (EXISTS ${TEST_3RDPARTY_DIR}) endif (EXISTS ${TEST_3RDPARTY_DIR})
# override CMake default RelWithDebInfo flags. This is important to ensure
# good performance
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Zi /O2 /Ob2 /D NDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Zi /O2 /Ob2 /D NDEBUG")
else (MSVC) else (MSVC)
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted") set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
endif (MSVC) endif (MSVC)
@@ -183,24 +138,14 @@ endif (MSVC)
if (MSVC AND MSVC_3RDPARTY_ROOT) if (MSVC AND MSVC_3RDPARTY_ROOT)
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}") message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
string(SUBSTRING ${MSVC_VERSION} 0 2 MSVC_VERSION_MAJOR)
string(SUBSTRING ${MSVC_VERSION} 2 2 MSVC_VERSION_MINOR)
set( OSG_MSVC "msvc" ) set( OSG_MSVC "msvc" )
if (${MSVC_VERSION_MAJOR} EQUAL "19") if (${MSVC_VERSION} EQUAL 1900)
if (${MSVC_VERSION_MINOR} GREATER_EQUAL "20")
set( OSG_MSVC ${OSG_MSVC}142 )
elseif (${MSVC_VERSION_MINOR} GREATER_EQUAL "10")
set( OSG_MSVC ${OSG_MSVC}141 )
else ()
set( OSG_MSVC ${OSG_MSVC}140 ) set( OSG_MSVC ${OSG_MSVC}140 )
endif () elseif (${MSVC_VERSION} EQUAL 1800)
elseif (${MSVC_VERSION_MAJOR} EQUAL "18")
set( OSG_MSVC ${OSG_MSVC}120 ) set( OSG_MSVC ${OSG_MSVC}120 )
else () else ()
message(FATAL_ERROR "Visual Studio 2013 or higher is required") message(FATAL_ERROR "Visual Studio 2013/2015 is required now")
endif () endif ()
if (CMAKE_CL_64) if (CMAKE_CL_64)
set( OSG_MSVC ${OSG_MSVC}-64 ) set( OSG_MSVC ${OSG_MSVC}-64 )
set( MSVC_3RDPARTY_DIR 3rdParty.x64 ) set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
@@ -215,13 +160,16 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
# if this variable was not set by the user, set it to 3rdparty root's # if this variable was not set by the user, set it to 3rdparty root's
# parent dir, which is the normal location for people using our # parent dir, which is the normal location for people using our
# windows-3rd-party repo # windows-3rd-party repo
get_filename_component(MSVC_ROOT_PARENT_DIR ${MSVC_3RDPARTY_ROOT} DIRECTORY) GET_FILENAME_COMPONENT(MSVC_ROOT_PARENT_DIR ${MSVC_3RDPARTY_ROOT} PATH)
set(BOOST_INCLUDEDIR ${MSVC_ROOT_PARENT_DIR}) set(BOOST_INCLUDEDIR ${MSVC_ROOT_PARENT_DIR})
message(STATUS "BOOST_INCLUDEDIR is ${BOOST_INCLUDEDIR}") message(STATUS "BOOST_INCLUDEDIR is ${BOOST_INCLUDEDIR}")
endif() endif()
if (NOT USE_AEONWAVE)
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include) set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib) set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
message(STATUS "OPENAL_INCLUDE_DIR is ${OPENAL_INCLUDE_DIR}")
endif()
endif (MSVC AND MSVC_3RDPARTY_ROOT) endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE) if(APPLE)
@@ -233,7 +181,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD
endif() endif()
find_package(Boost REQUIRED) find_package(Boost REQUIRED)
set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION -DBOOST_NO_STDLIB_CONFIG") set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION")
include(BoostTestTargets) include(BoostTestTargets)
if(SIMGEAR_HEADLESS) if(SIMGEAR_HEADLESS)
@@ -245,19 +193,12 @@ else()
if (ENABLE_SOUND) if (ENABLE_SOUND)
if (USE_AEONWAVE) if (USE_AEONWAVE)
find_package(AAX) find_package(AAX COMPONENTS aax REQUIRED)
endif() else()
if(NOT AAX_FOUND)
set(USE_AEONWAVE FALSE)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
endif() endif()
if(AAX_FOUND) message(STATUS "Sound support: ENABLED")
message(STATUS "Sound support: AeonWave")
else()
message(STATUS "Sound support: OpenAL")
endif()
endif(ENABLE_SOUND) endif(ENABLE_SOUND)
find_package(OpenSceneGraph 3.2.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgViewer osgUtil) find_package(OpenSceneGraph 3.2.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgViewer osgUtil)
@@ -278,15 +219,7 @@ else()
endif() endif()
endif(SIMGEAR_HEADLESS) endif(SIMGEAR_HEADLESS)
if(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
# As of 2020-08-01, OpenBSD's system zlib is slightly old, but it's usable
# with a workaround in simgear/io/iostreams/gzfstream.cxx.
find_package(ZLIB 1.2.3 REQUIRED)
else()
find_package(ZLIB 1.2.4 REQUIRED) find_package(ZLIB 1.2.4 REQUIRED)
endif()
find_package(LibLZMA REQUIRED)
find_package(CURL REQUIRED) find_package(CURL REQUIRED)
if (SYSTEM_EXPAT) if (SYSTEM_EXPAT)
@@ -296,6 +229,9 @@ if (SYSTEM_EXPAT)
else() else()
message(STATUS "Using built-in expat code") message(STATUS "Using built-in expat code")
# XML_STATIC is important to avoid sg_expat_external.h
# declaring symbols as declspec(import)
add_definitions(-DHAVE_EXPAT_CONFIG_H -DXML_STATIC)
set(EXPAT_INCLUDE_DIRS set(EXPAT_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/3rdparty/expat ${PROJECT_SOURCE_DIR}/3rdparty/expat
${PROJECT_BINARY_DIR}/3rdparty/expat) ${PROJECT_BINARY_DIR}/3rdparty/expat)
@@ -303,6 +239,7 @@ endif(SYSTEM_EXPAT)
check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(windows.h HAVE_WINDOWS_H) check_include_file(windows.h HAVE_WINDOWS_H)
@@ -312,40 +249,21 @@ if(HAVE_INTTYPES_H)
endif() endif()
if(ENABLE_RTI) if(ENABLE_RTI)
find_package(PkgConfig) # See if we have any rti library variant installed
if(PKG_CONFIG_FOUND)
SET(ENV{PKG_CONFIG_PATH} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}")
pkg_check_modules(RTI hla-rti13)
endif(PKG_CONFIG_FOUND)
if(RTI_FOUND)
message(STATUS "RTI: ENABLED") message(STATUS "RTI: ENABLED")
else() find_package(RTI)
message(STATUS "RTI: DISABLED")
endif(RTI_FOUND)
else() else()
message(STATUS "RTI: DISABLED") message(STATUS "RTI: DISABLED")
endif(ENABLE_RTI) endif(ENABLE_RTI)
if(ENABLE_GDAL)
find_package(GDAL 2.0.0 REQUIRED)
if (GDAL_FOUND)
include_directories(${GDAL_INCLUDE_DIR})
endif(GDAL_FOUND)
endif(ENABLE_GDAL)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(timegm HAVE_TIMEGM)
check_function_exists(rint HAVE_RINT) check_function_exists(rint HAVE_RINT)
check_function_exists(mkdtemp HAVE_MKDTEMP) check_function_exists(mkdtemp HAVE_MKDTEMP)
check_function_exists(bcopy HAVE_BCOPY) check_function_exists(bcopy HAVE_BCOPY)
check_function_exists(mmap HAVE_MMAP) check_function_exists(mmap HAVE_MMAP)
if (NOT MSVC)
check_function_exists(timegm HAVE_TIMEGM)
if (NOT HAVE_TIMEGM)
message(FATAL_ERROR "Non-Windows platforms must support timegm()")
endif()
endif()
if(HAVE_UNISTD_H) if(HAVE_UNISTD_H)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH}) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles( check_cxx_source_compiles(
@@ -390,7 +308,7 @@ SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on wi
# isnan might not be real symbol, so can't check using function_exists # isnan might not be real symbol, so can't check using function_exists
check_cxx_source_compiles( check_cxx_source_compiles(
"#include <cmath> "#include <cstdlib>
int main() { return std::isnan(0.0);} " int main() { return std::isnan(0.0);} "
HAVE_STD_ISNAN) HAVE_STD_ISNAN)
@@ -398,81 +316,37 @@ if (NOT ${HAVE_STD_ISNAN})
message(FATAL_ERROR "Your compiler lacks C++11 std::isnan, please update it") message(FATAL_ERROR "Your compiler lacks C++11 std::isnan, please update it")
endif() endif()
# Check if the <regex> implementation in the C++ standard library is usable.
# This is necessary because g++ 4.8 lies about its C++11 compliance: its
# <regex> is utterly unusable, cf. [1].
# The big preprocessor test essentially comes from [2], and gcc upstream devs
# appear to back it (see comments following [2], as well as [3]).
#
# [1] https://stackoverflow.com/a/12665408/4756009
# [2] https://stackoverflow.com/a/41186162/4756009
# [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78905
check_cxx_source_compiles(
"#include <regex>
int main() {
#if __cplusplus >= 201103L && \
(!defined(__GLIBCXX__) || \
(__cplusplus >= 201402L) || \
defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4))
#else
nullptr = void; // intentionally trigger a compilation error
#endif
}"
HAVE_WORKING_STD_REGEX)
if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS_CXX "-Wall -fPIC") set(WARNING_FLAGS_CXX "-Wall")
set(WARNING_FLAGS_C "-Wall -fPIC") set(WARNING_FLAGS_C "-Wall")
if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
message(WARNING "GCC 4.4 will be required soon, please upgrade") message(WARNING "GCC 4.4 will be required soon, please upgrade")
endif() endif()
if (X86 OR X86_64)
set(SIMD_COMPILER_FLAGS "-msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
endif()
# certain GCC versions don't provide the atomic builds, and hence # certain GCC versions don't provide the atomic builds, and hence
# require is to provide them in SGAtomic.cxx # require is to provide them in SGAtomic.cxx
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH}) set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
check_cxx_source_compiles( check_cxx_source_compiles(
"int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }" "int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }"
GCC_ATOMIC_BUILTINS_FOUND) GCC_ATOMIC_BUILTINS_FOUND)
# override CMake default RelWithDebInfo flags.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG")
endif(CMAKE_COMPILER_IS_GNUCXX) endif(CMAKE_COMPILER_IS_GNUCXX)
if (CLANG) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# Boost redeclares class members # Boost redeclares class members
set(WARNING_FLAGS_CXX "-Wall -fPIC -Wno-overloaded-virtual -Wno-redeclared-class-member") set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall -fPIC") set(WARNING_FLAGS_C "-Wall")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
# fix Boost compilation :( # fix Boost compilation :(
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
# override CMake default RelWithDebInfo flags. if (CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG")
set(SIMD_COMPILER_FLAGS "-msse2 -mfpmath=sse -ftree-vectorize -ftree-slp-vectorize")
endif() endif()
if (ENABLE_OPENMP)
find_package(OpenMP)
if(OPENMP_FOUND)
message(STATUS "OpenMP: ENABLED")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else()
message(STATUS "OpenMP: NOT FOUND")
endif()
else()
message(STATUS "OpenMP: DISABLED")
endif() endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -491,9 +365,6 @@ if(WIN32)
if(MSVC) if(MSVC)
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /MP") set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /MP")
if (X86)
set(SIMD_COMPILER_FLAGS "/arch:SSE /arch:SSE2")
endif()
if (NOT OSG_FSTREAM_EXPORT_FIXED) if (NOT OSG_FSTREAM_EXPORT_FIXED)
message(STATUS "For better linking performance, use OSG with patched fstream header") message(STATUS "For better linking performance, use OSG with patched fstream header")
@@ -516,34 +387,14 @@ if(WIN32)
set( RT_LIBRARY "winmm" ) set( RT_LIBRARY "winmm" )
endif(WIN32) endif(WIN32)
# append the SIMD flags if requested
if (ENABLE_SIMD)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SIMD_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SIMD_COMPILER_FLAGS}")
# set for multi-configuration generators
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${SIMD_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${SIMD_COMPILER_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${SIMD_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${SIMD_COMPILER_FLAGS}")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
include(CheckCXXFeatures)
# use BEFORE to ensure local directories are used first, # use BEFORE to ensure local directories are used first,
# ahead of system-installed libs # ahead of system-installed libs
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear) include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
if(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
include_directories("/usr/X11R6/include")
endif()
add_definitions(-DHAVE_CONFIG_H) add_definitions(-DHAVE_CONFIG_H)
# configure a header file to pass some of the CMake settings # configure a header file to pass some of the CMake settings
@@ -572,8 +423,7 @@ set(TEST_LIBS_INTERNAL_CORE
${RT_LIBRARY} ${RT_LIBRARY}
${DL_LIBRARY} ${DL_LIBRARY}
${COCOA_LIBRARY} ${COCOA_LIBRARY}
${CURL_LIBRARIES} ${CURL_LIBRARIES})
${GDAL_LIBRARY})
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE}) set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
+7 -13
View File
@@ -46,17 +46,11 @@ set(BOOST_TEST_TARGET_PREFIX "test")
if(NOT Boost_FOUND) if(NOT Boost_FOUND)
find_package(Boost 1.34.0 QUIET) find_package(Boost 1.34.0 QUIET)
endif() endif()
if("${Boost_VERSION}0" LESS "1034000")
if (NOT Boost_VERSION_MACRO)
# Compatibility with pre CMP0093 (CMake 3.15)
set(Boost_VERSION_MACRO ${Boost_VERSION})
endif()
if("${Boost_VERSION_MACRO}0" LESS "1034000")
set(_shared_msg set(_shared_msg
"NOTE: boost::test-based targets and tests cannot " "NOTE: boost::test-based targets and tests cannot "
"be added: boost >= 1.34.0 required but not found. " "be added: boost >= 1.34.0 required but not found. "
"(found: '${Boost_VERSION_MACRO}'; want >=103400) ") "(found: '${Boost_VERSION}'; want >=103400) ")
if(ENABLE_TESTS) if(ENABLE_TESTS)
message(FATAL_ERROR message(FATAL_ERROR
${_shared_msg} ${_shared_msg}
@@ -72,7 +66,7 @@ endif()
include(GetForceIncludeDefinitions) include(GetForceIncludeDefinitions)
include(CopyResourcesToBuildTree) include(CopyResourcesToBuildTree)
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000") if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
set(_boosttesttargets_libs) set(_boosttesttargets_libs)
set(_boostConfig "BoostTestTargetsIncluded.h") set(_boostConfig "BoostTestTargetsIncluded.h")
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY) if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
@@ -86,7 +80,7 @@ if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000")
set(_boostConfig "BoostTestTargetsDynamic.h") set(_boostConfig "BoostTestTargetsDynamic.h")
endif() endif()
endif() endif()
get_filename_component(_moddir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY) get_filename_component(_moddir ${CMAKE_CURRENT_LIST_FILE} PATH)
configure_file("${_moddir}/${_boostConfig}" configure_file("${_moddir}/${_boostConfig}"
"${CMAKE_CURRENT_BINARY_DIR}/BoostTestTargetConfig.h" "${CMAKE_CURRENT_BINARY_DIR}/BoostTestTargetConfig.h"
COPYONLY) COPYONLY)
@@ -135,7 +129,7 @@ function(add_boost_test _name)
"Syntax error in use of add_boost_test: at least one source file required!") "Syntax error in use of add_boost_test: at least one source file required!")
endif() endif()
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000") if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
@@ -163,7 +157,7 @@ function(add_boost_test _name)
endforeach() endforeach()
if(NOT _boostTestTargetsNagged${_name} STREQUAL "${includeType}") if(NOT _boostTestTargetsNagged${_name} STREQUAL "${includeType}")
if("${includeType}" STREQUAL "CONFIGURED") if("includeType" STREQUAL "CONFIGURED")
message(STATUS message(STATUS
"Test '${_name}' uses the CMake-configurable form of the boost test framework - congrats! (Including File: ${includeFileLoc})") "Test '${_name}' uses the CMake-configurable form of the boost test framework - congrats! (Including File: ${includeFileLoc})")
elseif("${includeType}" STREQUAL "INCLUDED") elseif("${includeType}" STREQUAL "INCLUDED")
@@ -227,7 +221,7 @@ function(add_boost_test _name)
set(_test_command ${_target_name}) set(_test_command ${_target_name})
endif() endif()
if(TESTS AND ( "${Boost_VERSION_MACRO}" VERSION_GREATER "103799" )) if(TESTS AND ( "${Boost_VERSION}" VERSION_GREATER "103799" ))
foreach(_test ${TESTS}) foreach(_test ${TESTS})
add_test( add_test(
${_name}-${_test} ${_name}-${_test}
-30
View File
@@ -1,30 +0,0 @@
check_cxx_source_compiles("
#include <utility>
#include <type_traits>
std::make_index_sequence<0> t;
int main() {}" HAVE_STD_INDEX_SEQUENCE
)
check_cxx_source_compiles("
#include <type_traits>
std::remove_cv_t<const int> t;
int main() {}" HAVE_STD_REMOVE_CV_T
)
check_cxx_source_compiles("
#include <type_traits>
std::remove_cvref_t<const int&> t;
int main() {}" HAVE_STD_REMOVE_CVREF_T
)
check_cxx_source_compiles("
#include <type_traits>
std::enable_if_t<true, int> t;
int main() {}" HAVE_STD_ENABLE_IF_T
)
check_cxx_source_compiles("
#include <type_traits>
std::bool_constant<true> t;
int main() {}" HAVE_STD_BOOL_CONSTANT
)
+2 -2
View File
@@ -30,12 +30,12 @@ function(copy_resources_to_build_tree _target)
endif() endif()
get_target_property(_path ${_target} LOCATION) get_target_property(_path ${_target} LOCATION)
get_filename_component(_path "${_path}" DIRECTORY) get_filename_component(_path "${_path}" PATH)
if(NOT MSVC AND NOT "${CMAKE_GENERATOR}" MATCHES "Makefiles") if(NOT MSVC AND NOT "${CMAKE_GENERATOR}" MATCHES "Makefiles")
foreach(_config ${CMAKE_CONFIGURATION_TYPES}) foreach(_config ${CMAKE_CONFIGURATION_TYPES})
get_target_property(_path${_config} ${_target} LOCATION_${_config}) get_target_property(_path${_config} ${_target} LOCATION_${_config})
get_filename_component(_path${_config} "${_path${_config}}" DIRECTORY) get_filename_component(_path${_config} "${_path${_config}}" PATH)
add_custom_command(TARGET ${_target} add_custom_command(TARGET ${_target}
POST_BUILD POST_BUILD
COMMAND COMMAND
-37
View File
@@ -1,37 +0,0 @@
IF(CMAKE_SYSTEM_PROCESSOR MATCHES amd64.*|x86_64.* OR CMAKE_GENERATOR MATCHES "Visual Studio.*Win64")
IF(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
SET(X86 1)
ELSE(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
SET(X86_64 1)
ENDIF(CMAKE_C_FLAGS MATCHES -m32 OR CMAKE_CXX_FLAGS MATCHES -m32)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES i686.*|i386.*|x86.* OR WIN32)
IF(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
SET(X86_64 1)
ELSE(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
SET(X86 1)
ENDIF(CMAKE_C_FLAGS MATCHES -m64 OR CMAKE_CXX_FLAGS MATCHES -m64)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES arm.* AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(ARM 1)
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES mips)
SET(MIPS 1)
ENDIF()
IF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
# using Clang
SET(CLANG 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "TinyCC")
# using TinyCC
SET(TINYCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
# using GCC
SET(GCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
SET(INTELCC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
SET(MSVC 1)
ELSEIF ("${CMAKE_C_COMPILER_ID}" STREQUAL "MIPSpro")
# using SGI MIPSpro
SET(MIPSPRO 1)
ENDIF()
-26
View File
@@ -1,26 +0,0 @@
# placehodler target for other ones to depend upon
add_custom_target(
debug_symbols
)
function(export_debug_symbols target)
if (NOT SIMGEAR_SHARED)
return()
endif()
if (APPLE)
add_custom_target(${target}.dSYM
COMMENT "Generating dSYM files for ${target}"
COMMAND dsymutil --out=${target}.dSYM $<TARGET_FILE:${target}>
DEPENDS $<TARGET_FILE:${target}>
)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${target}.dSYM DESTINATION symbols OPTIONAL)
add_dependencies(debug_symbols ${target}.dSYM)
endif()
endfunction()
+14 -40
View File
@@ -1,31 +1,21 @@
# Try to find AAX (AeonWave) # Locate AAX
# This module defines # This module defines
# # AAX_LIBRARIES
# AAX_FOUND - if false, do not try to link to AAX # AAX_FOUND, if false, do not try to link to AAX
# AAX_INCLUDE_DIR - where to find the headers # AAX_INCLUDE_DIR, where to find the headers
# AAX_LIBRARIES - Link these to use AAX
#
# Copyright (C) 2016-2018 by Erik Hofman.
# Copyright (C) 2016-2018 by Adalin B.V.
# #
# $AAXDIR is an environment variable that would # $AAXDIR is an environment variable that would
# correspond to the ./configure --prefix=$AAXDIR # correspond to the ./configure --prefix=$AAXDIR
# used in building AAX. # used in building AAX.
# #
# This file is Public Domain (www.unlicense.org) # Created by Erik Hofman.
# This is free and unencumbered software released into the public domain.
if (AAX_LIBRARY AND AAX_INCLUDE_DIR) FIND_PATH(AAX_INCLUDE_DIR aax/aeonwave.hpp
# in cache already
set(AAX_FOUND TRUE)
else()
find_path(AAX_INCLUDE_DIR aax/aax.h
HINTS HINTS
$ENV{AAXDIR} $ENV{AAXDIR}
$ENV{ProgramFiles}/aax $ENV{ProgramFiles}/aax
$ENV{ProgramFiles}/AeonWave $ENV{ProgramFiles}/AeonWave
$ENV{ProgramFiles}/Adalin/AeonWave $ENV{ProgramFiles}/Adalin/AeonWave
${CMAKE_SOURCE_DIR}/aax
PATH_SUFFIXES include PATH_SUFFIXES include
PATHS PATHS
~/Library/Frameworks ~/Library/Frameworks
@@ -35,40 +25,24 @@ else()
/opt /opt
) )
find_library(AAX_LIBRARY FIND_LIBRARY(AAX_LIBRARY
NAMES AAX aax libAAX NAMES AAX aax AAX32 libAAX32
HINTS HINTS
$ENV{AAXDIR} $ENV{AAXDIR}
$ENV{ProgramFiles}/AAX $ENV{ProgramFiles}/AAX
$ENV{ProgramFiles}/AeonWave $ENV{ProgramFiles}/AeonWave
$ENV{ProgramFiles}/Adalin/AeonWave $ENV{ProgramFiles}/Adalin/AeonWave
${CMAKE_BUILD_DIR}/aax PATH_SUFFIXES bin lib lib/${CMAKE_LIBRARY_ARCHITECTURE} lib64 libs64 libs libs/Win32 libs/Win64
PATH_SUFFIXES lib64 lib lib/${CMAKE_LIBRARY_ARCHITECTURE} libs64 libs libs/Win32 libs/Win64 bin
PATHS PATHS
~/Library/Frameworks ~/Library/Frameworks
/Library/Frameworks /Library/Frameworks
/usr/local
/usr /usr
/opt /opt
/usr/local
) )
set(AAX_DEFINITIONS "") SET(AAX_FOUND "NO")
if (AAX_LIBRARY AND AAX_INCLUDE_DIR) IF(AAX_LIBRARY AND AAX_INCLUDE_DIR)
set(AAX_FOUND TRUE) SET(AAX_FOUND "YES")
endif() ENDIF(AAX_LIBRARY AND AAX_INCLUDE_DIR)
if (AAX_FOUND)
if (NOT Udns_FIND_QUIETLY)
message(STATUS "Found AeonWave: ${AAX_LIBRARIES}")
endif ()
else ()
if (Udns_FIND_REQUIRED)
message(FATAL_ERROR "Could not find AeonWave")
endif ()
endif ()
# show the AAX_INCLUDE_DIRS and AAX_LIBRARIES variables only in the advanced view
mark_as_advanced(AAX_INCLUDE_DIRS AAX_LIBRARIES)
endif()
-124
View File
@@ -1,124 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindLibLZMA
-----------
Find LZMA compression algorithm headers and library.
Imported Targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``LibLZMA::LibLZMA``, if
liblzma has been found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``LIBLZMA_FOUND``
True if liblzma headers and library were found.
``LIBLZMA_INCLUDE_DIRS``
Directory where liblzma headers are located.
``LIBLZMA_LIBRARIES``
Lzma libraries to link against.
``LIBLZMA_HAS_AUTO_DECODER``
True if lzma_auto_decoder() is found (required).
``LIBLZMA_HAS_EASY_ENCODER``
True if lzma_easy_encoder() is found (required).
``LIBLZMA_HAS_LZMA_PRESET``
True if lzma_lzma_preset() is found (required).
``LIBLZMA_VERSION_MAJOR``
The major version of lzma
``LIBLZMA_VERSION_MINOR``
The minor version of lzma
``LIBLZMA_VERSION_PATCH``
The patch version of lzma
``LIBLZMA_VERSION_STRING``
version number as a string (ex: "5.0.3")
#]=======================================================================]
find_path(LIBLZMA_INCLUDE_DIR lzma.h )
if(NOT LIBLZMA_LIBRARY)
find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma NAMES_PER_DIR PATH_SUFFIXES lib)
find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad NAMES_PER_DIR PATH_SUFFIXES lib)
include(SelectLibraryConfigurations)
select_library_configurations(LIBLZMA)
else()
file(TO_CMAKE_PATH "${LIBLZMA_LIBRARY}" LIBLZMA_LIBRARY)
endif()
if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
file(STRINGS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h" LIBLZMA_HEADER_CONTENTS REGEX "#define LZMA_VERSION_[A-Z]+ [0-9]+")
string(REGEX REPLACE ".*#define LZMA_VERSION_MAJOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MAJOR "${LIBLZMA_HEADER_CONTENTS}")
string(REGEX REPLACE ".*#define LZMA_VERSION_MINOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MINOR "${LIBLZMA_HEADER_CONTENTS}")
string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")
set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
unset(LIBLZMA_HEADER_CONTENTS)
endif()
# We're using new code known now as XZ, even library still been called LZMA
# it can be found in http://tukaani.org/xz/
# Avoid using old codebase
if (LIBLZMA_LIBRARY)
include(CheckLibraryExists)
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ${LibLZMA_FIND_QUIETLY})
if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY})
elseif(LIBLZMA_LIBRARY_RELEASE)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_RELEASE})
elseif(LIBLZMA_LIBRARY_DEBUG)
set(LIBLZMA_LIBRARY_check ${LIBLZMA_LIBRARY_DEBUG})
endif()
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_auto_decoder "" LIBLZMA_HAS_AUTO_DECODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_easy_encoder "" LIBLZMA_HAS_EASY_ENCODER)
CHECK_LIBRARY_EXISTS(${LIBLZMA_LIBRARY_check} lzma_lzma_preset "" LIBLZMA_HAS_LZMA_PRESET)
unset(LIBLZMA_LIBRARY_check)
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
endif ()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibLZMA REQUIRED_VARS LIBLZMA_LIBRARY
LIBLZMA_INCLUDE_DIR
LIBLZMA_HAS_AUTO_DECODER
LIBLZMA_HAS_EASY_ENCODER
LIBLZMA_HAS_LZMA_PRESET
VERSION_VAR LIBLZMA_VERSION_STRING
)
mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )
if (LIBLZMA_FOUND)
set(LIBLZMA_LIBRARIES ${LIBLZMA_LIBRARY})
set(LIBLZMA_INCLUDE_DIRS ${LIBLZMA_INCLUDE_DIR})
if(NOT TARGET LibLZMA::LibLZMA)
add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${LIBLZMA_INCLUDE_DIR}
IMPORTED_LINK_INTERFACE_LANGUAGES C)
if(LIBLZMA_LIBRARY_RELEASE)
set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION_RELEASE "${LIBLZMA_LIBRARY_RELEASE}")
endif()
if(LIBLZMA_LIBRARY_DEBUG)
set_property(TARGET LibLZMA::LibLZMA APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION_DEBUG "${LIBLZMA_LIBRARY_DEBUG}")
endif()
if(NOT LIBLZMA_LIBRARY_RELEASE AND NOT LIBLZMA_LIBRARY_DEBUG)
set_target_properties(LibLZMA::LibLZMA PROPERTIES
IMPORTED_LOCATION "${LIBLZMA_LIBRARY}")
endif()
endif()
endif ()
-5
View File
@@ -12,11 +12,6 @@ macro(simgear_component_common name includePath sourcesList sources headers)
set_property(GLOBAL set_property(GLOBAL
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}") APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
set(fh${sourcesList} "${fh${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${h}") set(fh${sourcesList} "${fh${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${h}")
# also append headers to the sources list, so that IDEs find the files
# correctly (otherwise they are not in the project)
set_property(GLOBAL
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
endforeach() endforeach()
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_C "${fc${sourcesList}}@") set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_C "${fc${sourcesList}}@")
+145 -283
View File
@@ -1,4 +1,4 @@
# Doxyfile 1.8.13 # Doxyfile 1.8.6
# This file describes the settings to be used by the documentation system # This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project. # doxygen (www.doxygen.org) for a project.
@@ -38,7 +38,7 @@ PROJECT_NAME = SimGear
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 2019.2.0 PROJECT_NUMBER = 3.3.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
@@ -46,10 +46,10 @@ PROJECT_NUMBER = 2019.2.0
PROJECT_BRIEF = PROJECT_BRIEF =
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included # With the PROJECT_LOGO tag one can specify an logo or icon that is included in
# in the documentation. The maximum height of the logo should not exceed 55 # the documentation. The maximum height of the logo should not exceed 55 pixels
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
# the logo to the output directory. # to the output directory.
PROJECT_LOGO = PROJECT_LOGO =
@@ -58,9 +58,9 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If # entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used. # left blank the current directory will be used.
OUTPUT_DIRECTORY = ../docs/SimGear OUTPUT_DIRECTORY = ../doxy
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and # directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this # will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where # option can be useful when feeding doxygen a huge amount of source files, where
@@ -70,14 +70,6 @@ OUTPUT_DIRECTORY = ../docs/SimGear
CREATE_SUBDIRS = NO CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
# U+3044.
# The default value is: NO.
ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all # The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this # documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language. # information to generate all constant output in the proper language.
@@ -93,14 +85,14 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
# descriptions after the members that are listed in the file and class # descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this. # documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES. # The default value is: YES.
BRIEF_MEMBER_DESC = YES BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
# description of a member or function before the detailed description # description of a member or function before the detailed description
# #
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
@@ -135,7 +127,7 @@ ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the # before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used # shortest path that makes the file name unique will be used
# The default value is: YES. # The default value is: YES.
@@ -205,9 +197,9 @@ MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
# page for each member. If set to NO, the documentation of a member will be part # new page for each member. If set to NO, the documentation of a member will be
# of the file/class/namespace that contains it. # part of the file/class/namespace that contains it.
# The default value is: NO. # The default value is: NO.
SEPARATE_MEMBER_PAGES = NO SEPARATE_MEMBER_PAGES = NO
@@ -269,14 +261,11 @@ OPTIMIZE_OUTPUT_VHDL = NO
# extension. Doxygen has a built-in mapping, but you can override or extend it # extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and # using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript, # language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# Fortran. In the later case the parser tries to guess whether the code is fixed # (default is Fortran), use: inc=Fortran f=C.
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
# #
# Note: For files without extension you can use no_extension as a placeholder. # Note For files without extension you can use no_extension as a placeholder.
# #
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise # Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen. # the files are not read by doxygen.
@@ -293,19 +282,10 @@ EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES MARKDOWN_SUPPORT = YES
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 0.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
TOC_INCLUDE_HEADINGS = 0
# When enabled doxygen tries to link words that correspond to documented # When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can # classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or # be prevented in individual cases by by putting a % sign in front of the word
# globally by setting AUTOLINK_SUPPORT to NO. # or globally by setting AUTOLINK_SUPPORT to NO.
# The default value is: YES. # The default value is: YES.
AUTOLINK_SUPPORT = YES AUTOLINK_SUPPORT = YES
@@ -345,20 +325,13 @@ SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES then doxygen will reuse the documentation of the first # tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default # member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly. # all members of a group must be documented explicitly.
# The default value is: NO. # The default value is: NO.
DISTRIBUTE_GROUP_DOC = NO DISTRIBUTE_GROUP_DOC = NO
# If one adds a struct or class to a group and this option is enabled, then also
# any nested class or struct is added to the same group. By default this option
# is disabled and one has to add nested compounds explicitly via \ingroup.
# The default value is: NO.
GROUP_NESTED_COMPOUNDS = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type # Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that # (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent # type (e.g. under the Public Functions section). Set it to NO to prevent
@@ -417,7 +390,7 @@ LOOKUP_CACHE_SIZE = 0
# Build related configuration options # Build related configuration options
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available. Private # documentation are documented, even if no documentation was available. Private
# class members and static file members will be hidden unless the # class members and static file members will be hidden unless the
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
@@ -425,37 +398,37 @@ LOOKUP_CACHE_SIZE = 0
# normally produced when WARNINGS is set to YES. # normally produced when WARNINGS is set to YES.
# The default value is: NO. # The default value is: NO.
EXTRACT_ALL = YES EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
# be included in the documentation. # be included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_PRIVATE = NO EXTRACT_PRIVATE = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
# scope will be included in the documentation. # scope will be included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_PACKAGE = NO EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # If the EXTRACT_STATIC tag is set to YES all static members of a file will be
# included in the documentation. # included in the documentation.
# The default value is: NO. # The default value is: NO.
EXTRACT_STATIC = YES EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO, # locally in source files will be included in the documentation. If set to NO
# only classes defined in header files are included. Does not have any effect # only classes defined in header files are included. Does not have any effect
# for Java sources. # for Java sources.
# The default value is: YES. # The default value is: YES.
EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_CLASSES = YES
# This flag is only useful for Objective-C code. If set to YES, local methods, # This flag is only useful for Objective-C code. When set to YES local methods,
# which are defined in the implementation section but not in the interface are # which are defined in the implementation section but not in the interface are
# included in the documentation. If set to NO, only methods in the interface are # included in the documentation. If set to NO only methods in the interface are
# included. # included.
# The default value is: NO. # The default value is: NO.
@@ -480,21 +453,21 @@ HIDE_UNDOC_MEMBERS = YES
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set # undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option # to NO these classes will be included in the various overviews. This option has
# has no effect if EXTRACT_ALL is enabled. # no effect if EXTRACT_ALL is enabled.
# The default value is: NO. # The default value is: NO.
HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_CLASSES = YES
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be # (class|struct|union) declarations. If set to NO these declarations will be
# included in the documentation. # included in the documentation.
# The default value is: NO. # The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
# documentation blocks found inside the body of a function. If set to NO, these # documentation blocks found inside the body of a function. If set to NO these
# blocks will be appended to the function's detailed documentation block. # blocks will be appended to the function's detailed documentation block.
# The default value is: NO. # The default value is: NO.
@@ -508,7 +481,7 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also # names in lower-case letters. If set to YES upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ # allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows # in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO. # and Mac users are advised to set this option to NO.
@@ -517,19 +490,12 @@ INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES, the # their full class and namespace scopes in the documentation. If set to YES the
# scope will be hidden. # scope will be hidden.
# The default value is: NO. # The default value is: NO.
HIDE_SCOPE_NAMES = NO HIDE_SCOPE_NAMES = NO
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
# YES the compound reference will be hidden.
# The default value is: NO.
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file. # the files that are included by a file in the documentation of that file.
# The default value is: YES. # The default value is: YES.
@@ -557,14 +523,14 @@ INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member # (detailed) documentation of file and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order. # name. If set to NO the members will appear in declaration order.
# The default value is: YES. # The default value is: YES.
SORT_MEMBER_DOCS = YES SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member # descriptions of file, namespace and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order. Note that # name. If set to NO the members will appear in declaration order. Note that
# this will also influence the order of the classes in the class list. # this will also influence the order of the classes in the class list.
# The default value is: NO. # The default value is: NO.
@@ -609,14 +575,16 @@ SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO STRICT_PROTO_MATCHING = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
# list. This list is created by putting \todo commands in the documentation. # todo list. This list is created by putting \todo commands in the
# documentation.
# The default value is: YES. # The default value is: YES.
GENERATE_TODOLIST = YES GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
# list. This list is created by putting \test commands in the documentation. # test list. This list is created by putting \test commands in the
# documentation.
# The default value is: YES. # The default value is: YES.
GENERATE_TESTLIST = YES GENERATE_TESTLIST = YES
@@ -652,8 +620,8 @@ ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30 MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
# the bottom of the documentation of classes and structs. If set to YES, the # the bottom of the documentation of classes and structs. If set to YES the list
# list will mention the files that were used to generate the documentation. # will mention the files that were used to generate the documentation.
# The default value is: YES. # The default value is: YES.
SHOW_USED_FILES = YES SHOW_USED_FILES = YES
@@ -701,7 +669,8 @@ LAYOUT_FILE =
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using # For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references. # search path. Do not use file names with spaces, bibtex cannot handle them. See
# also \cite for info how to create references.
CITE_BIB_FILES = CITE_BIB_FILES =
@@ -725,7 +694,7 @@ QUIET = NO
WARNINGS = YES WARNINGS = YES
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled. # will automatically be disabled.
# The default value is: YES. # The default value is: YES.
@@ -742,18 +711,12 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return # are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete # value. If set to NO doxygen will only warn about wrong or incomplete parameter
# parameter documentation, but not about the absence of documentation. # documentation, but not about the absence of documentation.
# The default value is: NO. # The default value is: NO.
WARN_NO_PARAMDOC = NO WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen # The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which # can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated # will be replaced by the file and line number from which the warning originated
@@ -777,7 +740,7 @@ WARN_LOGFILE =
# The INPUT tag is used to specify the files and/or directories that contain # The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or # documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with # directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces.
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = DoxygenMain.cxx \ INPUT = DoxygenMain.cxx \
@@ -794,17 +757,12 @@ INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the # If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories. # *.h) to filter out the source-files in the directories. If left blank the
# # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
# Note that for custom extensions or not directly supported extensions you also # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
# need to set EXTENSION_MAPPING for the extension otherwise the files are not # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
# read by doxygen. # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# # *.qsf, *.as and *.js.
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
FILE_PATTERNS = *.h \ FILE_PATTERNS = *.h \
*.hxx \ *.hxx \
@@ -894,10 +852,6 @@ IMAGE_PATH =
# Note that the filter must not add or remove lines; it is applied before the # Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added # code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly. # or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER = INPUT_FILTER =
@@ -907,10 +861,6 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied. # patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS = FILTER_PATTERNS =
@@ -975,7 +925,7 @@ REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
# to YES then the hyperlinks from functions in REFERENCES_RELATION and # to YES, then the hyperlinks from functions in REFERENCES_RELATION and
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
# link to the documentation. # link to the documentation.
# The default value is: YES. # The default value is: YES.
@@ -1022,25 +972,6 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index # Configuration options related to the alphabetical class index
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
@@ -1071,7 +1002,7 @@ IGNORE_PREFIX =
# Configuration options related to the HTML output # Configuration options related to the HTML output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
# The default value is: YES. # The default value is: YES.
GENERATE_HTML = YES GENERATE_HTML = YES
@@ -1133,15 +1064,13 @@ HTML_FOOTER =
HTML_STYLESHEET = HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
# cascading style sheets that are included after the standard style sheets # defined cascading style sheet that is included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects. # created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the # This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates. # standard style sheet and is therefor more robust against future updates.
# Doxygen will copy the style sheet files to the output directory. # Doxygen will copy the style sheet file to the output directory. For an example
# Note: The order of the extra style sheet files is of importance (e.g. the last # see the documentation.
# style sheet in the list overrules the setting of the previous ones in the
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET = HTML_EXTRA_STYLESHEET =
@@ -1188,9 +1117,8 @@ HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this # page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the # to NO can help when comparing the output of multiple runs.
# documentation is up to date. # The default value is: YES.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES HTML_TIMESTAMP = YES
@@ -1286,15 +1214,15 @@ GENERATE_HTMLHELP = NO
CHM_FILE = CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path # The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty, # including file name) of the HTML help compiler ( hhc.exe). If non-empty
# doxygen will try to run the HTML help compiler on the generated index.hhp. # doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path. # The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION = HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated # The GENERATE_CHI flag controls if a separate .chi index file is generated (
# (YES) or that it should be included in the master .chm file (NO). # YES) or that it should be included in the master .chm file ( NO).
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1306,9 +1234,8 @@ GENERATE_CHI = NO
CHM_INDEX_ENCODING = CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated # The BINARY_TOC flag controls whether a binary table of contents is generated (
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # YES) or a normal table of contents ( NO) in the .chm file.
# enables the Previous and Next buttons.
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
@@ -1449,7 +1376,7 @@ ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250 TREEVIEW_WIDTH = 250
# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
# external symbols imported via tag files in a separate window. # external symbols imported via tag files in a separate window.
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1478,7 +1405,7 @@ FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering # http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # instead of using prerendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When # installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path # enabled you may also need to install MathJax separately and configure the path
# to it using the MATHJAX_RELPATH option. # to it using the MATHJAX_RELPATH option.
@@ -1548,11 +1475,11 @@ SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There # implemented using a web server instead of a web client using Javascript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH # are two flavours of web server based searching depending on the
# setting. When disabled, doxygen will generate a PHP script for searching and # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing # searching and an index file used by the script. When EXTERNAL_SEARCH is
# and searching needs to be provided by external tools. See the section # enabled the indexing and searching needs to be provided by external tools. See
# "External Indexing and Searching" for details. # the section "External Indexing and Searching" for details.
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES. # This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1615,7 +1542,7 @@ EXTRA_SEARCH_MAPPINGS =
# Configuration options related to the LaTeX output # Configuration options related to the LaTeX output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
# The default value is: YES. # The default value is: YES.
GENERATE_LATEX = NO GENERATE_LATEX = NO
@@ -1646,7 +1573,7 @@ LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some # documents. This may be useful for small projects and may help to save some
# trees in general. # trees in general.
# The default value is: NO. # The default value is: NO.
@@ -1664,12 +1591,9 @@ COMPACT_LATEX = NO
PAPER_TYPE = letter PAPER_TYPE = letter
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. The package can be specified just # that should be included in the LaTeX output. To get the times font for
# by its name or with the correct syntax as to be used with the LaTeX # instance you can specify
# \usepackage command. To get the times font for instance you can specify : # EXTRA_PACKAGES=times
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
# To use the option intlimits with the amsmath package you can specify:
# EXTRA_PACKAGES=[intlimits]{amsmath}
# If left blank no extra packages will be included. # If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES. # This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1683,36 +1607,23 @@ EXTRA_PACKAGES =
# #
# Note: Only use a user-defined header if you know what you are doing! The # Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title, # following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber, # $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty # replace them by respectively the title of the page, the current date and time,
# string, for the replacement values of the other commands the user is referred # only the current date, the version number of doxygen, the project name (see
# to HTML_HEADER. # PROJECT_NAME), or the project number (see PROJECT_NUMBER).
# This tag requires that the tag GENERATE_LATEX is set to YES. # This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER = LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last # generated LaTeX document. The footer should contain everything after the last
# chapter. If it is left blank doxygen will generate a standard footer. See # chapter. If it is left blank doxygen will generate a standard footer.
# LATEX_HEADER for more information on how to generate a default footer and what
# special commands can be used inside the footer.
# #
# Note: Only use a user-defined footer if you know what you are doing! # Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES. # This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER = LATEX_FOOTER =
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# LaTeX style sheets that are included after the standard style sheets created
# by doxygen. Using this option one can overrule certain style aspects. Doxygen
# will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output # other source files which should be copied to the LATEX_OUTPUT output
# directory. Note that the files will be copied as-is; there are no commands or # directory. Note that the files will be copied as-is; there are no commands or
@@ -1730,8 +1641,8 @@ LATEX_EXTRA_FILES =
PDF_HYPERLINKS = NO PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
# the PDF file directly from the LaTeX files. Set this option to YES, to get a # the PDF file directly from the LaTeX files. Set this option to YES to get a
# higher quality PDF documentation. # higher quality PDF documentation.
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES. # This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1772,19 +1683,11 @@ LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the RTF output # Configuration options related to the RTF output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
# RTF output is optimized for Word 97 and may not look too pretty with other RTF # RTF output is optimized for Word 97 and may not look too pretty with other RTF
# readers/editors. # readers/editors.
# The default value is: NO. # The default value is: NO.
@@ -1799,7 +1702,7 @@ GENERATE_RTF = YES
RTF_OUTPUT = rtf RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
# documents. This may be useful for small projects and may help to save some # documents. This may be useful for small projects and may help to save some
# trees in general. # trees in general.
# The default value is: NO. # The default value is: NO.
@@ -1836,21 +1739,11 @@ RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE = RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the man page output # Configuration options related to the man page output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
# classes and files. # classes and files.
# The default value is: NO. # The default value is: NO.
@@ -1874,13 +1767,6 @@ MAN_OUTPUT = man
MAN_EXTENSION = .3 MAN_EXTENSION = .3
# The MAN_SUBDIR tag determines the name of the directory created within
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real # will generate one additional man file for each entity documented in the real
# man page(s). These additional files only source the real man page, but without # man page(s). These additional files only source the real man page, but without
@@ -1894,7 +1780,7 @@ MAN_LINKS = NO
# Configuration options related to the XML output # Configuration options related to the XML output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
# captures the structure of the code including all documentation. # captures the structure of the code including all documentation.
# The default value is: NO. # The default value is: NO.
@@ -1908,7 +1794,19 @@ GENERATE_XML = NO
XML_OUTPUT = xml XML_OUTPUT = xml
# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
# validating XML parser to check the syntax of the XML files.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_SCHEMA =
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
# validating XML parser to check the syntax of the XML files.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to # listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size # the XML output. Note that enabling this will significantly increase the size
# of the XML output. # of the XML output.
@@ -1921,7 +1819,7 @@ XML_PROGRAMLISTING = YES
# Configuration options related to the DOCBOOK output # Configuration options related to the DOCBOOK output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
# that can be used to generate PDF. # that can be used to generate PDF.
# The default value is: NO. # The default value is: NO.
@@ -1935,23 +1833,14 @@ GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output # Configuration options for the AutoGen Definitions output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an # If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
# AutoGen Definitions (see http://autogen.sf.net) file that captures the # Definitions (see http://autogen.sf.net) file that captures the structure of
# structure of the code including all documentation. Note that this feature is # the code including all documentation. Note that this feature is still
# still experimental and incomplete at the moment. # experimental and incomplete at the moment.
# The default value is: NO. # The default value is: NO.
GENERATE_AUTOGEN_DEF = NO GENERATE_AUTOGEN_DEF = NO
@@ -1960,7 +1849,7 @@ GENERATE_AUTOGEN_DEF = NO
# Configuration options related to the Perl module output # Configuration options related to the Perl module output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
# file that captures the structure of the code including all documentation. # file that captures the structure of the code including all documentation.
# #
# Note that this feature is still experimental and incomplete at the moment. # Note that this feature is still experimental and incomplete at the moment.
@@ -1968,7 +1857,7 @@ GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO GENERATE_PERLMOD = NO
# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
# output from the Perl module output. # output from the Perl module output.
# The default value is: NO. # The default value is: NO.
@@ -1976,9 +1865,9 @@ GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO PERLMOD_LATEX = NO
# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
# formatted so it can be parsed by a human reader. This is useful if you want to # formatted so it can be parsed by a human reader. This is useful if you want to
# understand what is going on. On the other hand, if this tag is set to NO, the # understand what is going on. On the other hand, if this tag is set to NO the
# size of the Perl module output will be much smaller and Perl will parse it # size of the Perl module output will be much smaller and Perl will parse it
# just the same. # just the same.
# The default value is: YES. # The default value is: YES.
@@ -1998,14 +1887,14 @@ PERLMOD_MAKEVAR_PREFIX =
# Configuration options related to the preprocessor # Configuration options related to the preprocessor
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
# C-preprocessor directives found in the sources and include files. # C-preprocessor directives found in the sources and include files.
# The default value is: YES. # The default value is: YES.
ENABLE_PREPROCESSING = YES ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names # If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
# in the source code. If set to NO, only conditional compilation will be # in the source code. If set to NO only conditional compilation will be
# performed. Macro expansion can be done in a controlled way by setting # performed. Macro expansion can be done in a controlled way by setting
# EXPAND_ONLY_PREDEF to YES. # EXPAND_ONLY_PREDEF to YES.
# The default value is: NO. # The default value is: NO.
@@ -2021,7 +1910,7 @@ MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the # If the SEARCH_INCLUDES tag is set to YES the includes files in the
# INCLUDE_PATH will be searched if a #include is found. # INCLUDE_PATH will be searched if a #include is found.
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -2063,9 +1952,9 @@ PREDEFINED =
EXPAND_AS_DEFINED = EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have # remove all refrences to function-like macros that are alone on a line, have an
# an all uppercase name, and do not end with a semicolon. Such function macros # all uppercase name, and do not end with a semicolon. Such function macros are
# are typically used for boiler-plate code, and will confuse the parser if not # typically used for boiler-plate code, and will confuse the parser if not
# removed. # removed.
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
@@ -2085,7 +1974,7 @@ SKIP_FUNCTION_MACROS = YES
# where loc1 and loc2 can be relative or absolute paths or URLs. See the # where loc1 and loc2 can be relative or absolute paths or URLs. See the
# section "Linking to external documentation" for more information about the use # section "Linking to external documentation" for more information about the use
# of tag files. # of tag files.
# Note: Each tag file must have a unique name (where the name does NOT include # Note: Each tag file must have an unique name (where the name does NOT include
# the path). If a tag file is not located in the directory in which doxygen is # the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here. # run, you must also specify the path to the tagfile here.
@@ -2097,21 +1986,20 @@ TAGFILES =
GENERATE_TAGFILE = GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in # If the ALLEXTERNALS tag is set to YES all external class will be listed in the
# the class index. If set to NO, only the inherited external classes will be # class index. If set to NO only the inherited external classes will be listed.
# listed.
# The default value is: NO. # The default value is: NO.
ALLEXTERNALS = NO ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
# in the modules index. If set to NO, only the current project's groups will be # the modules index. If set to NO, only the current project's groups will be
# listed. # listed.
# The default value is: YES. # The default value is: YES.
EXTERNAL_GROUPS = YES EXTERNAL_GROUPS = YES
# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
# the related pages index. If set to NO, only the current project's pages will # the related pages index. If set to NO, only the current project's pages will
# be listed. # be listed.
# The default value is: YES. # The default value is: YES.
@@ -2128,14 +2016,14 @@ PERL_PATH = /usr/bin/perl
# Configuration options related to the dot tool # Configuration options related to the dot tool
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT # NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more # disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs. # powerful graphs.
# The default value is: YES. # The default value is: YES.
CLASS_DIAGRAMS = NO CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc # You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see: # command. Doxygen will then run the mscgen tool (see:
@@ -2153,7 +2041,7 @@ MSCGEN_PATH =
DIA_PATH = DIA_PATH =
# If set to YES the inheritance and collaboration graphs will hide inheritance # If set to YES, the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class. # and usage relations if the target is undocumented or is not a class.
# The default value is: YES. # The default value is: YES.
@@ -2164,9 +2052,9 @@ HIDE_UNDOC_RELATIONS = YES
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is # Bell Labs. The other options in this section have no effect if this option is
# set to NO # set to NO
# The default value is: YES. # The default value is: NO.
HAVE_DOT = YES HAVE_DOT = NO
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of # to run in parallel. When set to 0 doxygen will base this on the number of
@@ -2178,7 +2066,7 @@ HAVE_DOT = YES
DOT_NUM_THREADS = 0 DOT_NUM_THREADS = 0
# When you want a differently looking font in the dot files that doxygen # When you want a differently looking font n the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make # generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a # sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by # standard location or by setting the DOTFONTPATH environment variable or by
@@ -2226,7 +2114,7 @@ COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES GROUP_GRAPHS = YES
# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # If the UML_LOOK tag is set to YES doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling # collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language. # Language.
# The default value is: NO. # The default value is: NO.
@@ -2278,24 +2166,22 @@ INCLUDED_BY_GRAPH = YES
# #
# Note that enabling this option will significantly increase the time of a run. # Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected # So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command. Disabling a call graph can be # functions only using the \callgraph command.
# accomplished by means of the command \hidecallgraph.
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = YES CALL_GRAPH = NO
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller # If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method. # dependency graph for every global function or class method.
# #
# Note that enabling this option will significantly increase the time of a run. # Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected # So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command. Disabling a caller graph can be # functions only using the \callergraph command.
# accomplished by means of the command \hidecallergraph.
# The default value is: NO. # The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = YES CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical # If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one. # hierarchy of all classes instead of a textual one.
@@ -2314,17 +2200,11 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section # generated by dot.
# output formats in the documentation of the dot tool (Graphviz (see:
# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this # to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement). # requirement).
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, # Possible values are: png, jpg, gif and svg.
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png. # The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
@@ -2367,24 +2247,6 @@ MSCFILE_DIRS =
DIAFILE_DIRS = DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
PLANTUML_JAR_PATH =
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
# configuration file for plantuml.
PLANTUML_CFG_FILE =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
PLANTUML_INCLUDE_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes # that will be shown in the graph. If the number of nodes in a graph becomes
# larger than this value, doxygen will truncate the graph, which is visualized # larger than this value, doxygen will truncate the graph, which is visualized
@@ -2421,7 +2283,7 @@ MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This # files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support # makes dot run faster, but since only newer versions of dot (>1.8.10) support
# this, this feature is disabled by default. # this, this feature is disabled by default.
@@ -2438,7 +2300,7 @@ DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
# files that are used to generate the various graphs. # files that are used to generate the various graphs.
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
-4
View File
@@ -2,10 +2,6 @@
documentation. It has a .cxx extension so that emacs will happily documentation. It has a .cxx extension so that emacs will happily
autoindent correctly. */ autoindent correctly. */
/**
* \namespace simgear
* \brief \ref index "SimGear" main namespace.
*/
/** \mainpage SimGear /** \mainpage SimGear
* Simulation, Visualization, and Game development libraries. * Simulation, Visualization, and Game development libraries.
+20
View File
@@ -0,0 +1,20 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://connect.creativelabs.com/openal/default.aspx
Build notes:
You can download a versioned release of the openal library from
http://www.openal.org/downloads.html. Download the openal source,
release 0.0.8 (dated February 11, 2006) and run:
tar xjvf openal-soft-1.5.304.tar.bz2
cd openal-soft-1.5.304/
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
-39
View File
@@ -1,39 +0,0 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
For Sound support FlightGear requires one of the two following packages:
- OpenAL
- AeonWave
== OpenAL ===
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://connect.creativelabs.com/openal/default.aspx
Build notes:
You can download a versioned release of the openal library from
http://www.openal.org/downloads.html. Download the openal source,
release 0.0.8 (dated February 11, 2006) and run:
tar xjvf openal-soft-1.5.304.tar.bz2
cd openal-soft-1.5.304/
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
== AeonWave ===
For FlightGear AeonWave has a number of advantages over OpenAL:
* Correct Doppler effect behavior
* Default distance attenuation frequency filtering
* Native support for 29 types of audio formats.
* Native support for wav, mp3, vorbis and raw file formats.
The source code of AeonWave can be found on GitHub:
https://github.com/adalinbv
Optimized binary packages are available at:
http://www.adalin.com/
+76
View File
@@ -0,0 +1,76 @@
%define ver @VERSION@
%define rel 1
%define prefix /usr
Summary: Simulator Construction Gear.
Name: @PACKAGE@
Version: %ver
Release: %rel
Copyright: LGPL
Group: Libraries/Graphics
Source: %{name}-%{version}.tar.gz
#URL:
BuildRoot: /tmp/%{name}-%{version}-%{rel}-root
Packager: Fill In As You Wish
Docdir: %{prefix}/doc
%description
This package contains a tools and libraries useful for constructing
simulation and visualization applications such as FlightGear or TerraGear.
Authors:
N/A
%prep
%setup -n %{name}-%{version}
%build
# Needed for snapshot releases.
if [ ! -f configure ]; then
CFLAGS="$RPM_OPT_FLAGS" ./autogen.sh --prefix=%prefix
else
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix
fi
if [ "$SMP" != "" ]; then
JSMP = '"MAKE=make -k -j $SMP"'
fi
make ${JSMP};
%install
[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
make prefix=${RPM_BUILD_ROOT}%{prefix} install
#
# Generating file lists and store them in file-lists
# Starting with the directory listings
#
find ${RPM_BUILD_ROOT}%{prefix}/{bin,include,lib} -type d | sed "s#^${RPM_BUILD_ROOT}#\%attr (-\,root\,root) \%dir #" > file-lists
%{?ETCDR:find ${RPM_BUILD_ROOT}%{!?SYSCF:%{prefix}}/etc -type d | sed "s#^${RPM_BUILD_ROOT}#\%attr (-\,root\,root) \%dir #" >> file-lists}
#
# Then, the file listings
#
echo "%defattr (-, root, root)" >> file-lists
%{?ETCDR:find ${RPM_BUILD_ROOT}%{!?SYSCF:%{prefix}}/etc/%{name}.conf -type f | sed -e "s#^${RPM_BUILD_ROOT}#%config #g" >> file-lists}
find ${RPM_BUILD_ROOT}%{prefix} -type f | sed -e "s#^${RPM_BUILD_ROOT}##g" >> file-lists
%clean
(cd ..; rm -rf %{name}-%{version} ${RPM_BUILD_ROOT})
%files -f file-lists
%defattr (-, root, root)
%doc AUTHORS
%doc COPYING
%doc ChangeLog
%doc INSTALL
%doc NEWS
%doc README
%doc %{name}.spec.in
-21
View File
@@ -1,37 +1,16 @@
include(CMakeFindDependencyMacro) include(CMakeFindDependencyMacro)
find_dependency(ZLIB) find_dependency(ZLIB)
find_dependency(LibLZMA)
find_dependency(Threads) find_dependency(Threads)
# OSG # OSG
set(SIMGEAR_HEADLESS @SIMGEAR_HEADLESS@) set(SIMGEAR_HEADLESS @SIMGEAR_HEADLESS@)
set(SIMGEAR_SOUND @ENABLE_SOUND@) set(SIMGEAR_SOUND @ENABLE_SOUND@)
set(USE_AEONWAVE @USE_AEONWAVE@)
# OpenAL isn't a public dependency, so maybe not needed # OpenAL isn't a public dependency, so maybe not needed
#if (SIMGEAR_SOUND) #if (SIMGEAR_SOUND)
# find_dependency(OpenAL) # find_dependency(OpenAL)
#endif() #endif()
# SSE/SSE2 support
set(ENABLE_SIMD @ENABLE_SIMD@)
# OpenRTI support
set(ENABLE_RTI @ENABLE_RTI@)
if(ENABLE_RTI)
set(RTI_FOUND @RTI_FOUND@)
if(RTI_FOUND)
set(RTI_INCLUDE_DIRS @RTI_INCLUDE_DIRS@)
set(RTI_LDFLAGS @RTI_LDFLAGS@)
endif(RTI_FOUND)
endif(ENABLE_RTI)
# Alternative terrain engine based on pagedLOD
set(ENABLE_GDAL @ENABLE_GDAL@)
set(ENABLE_OPENMP @ENABLE_OPENMP@)
include("${CMAKE_CURRENT_LIST_DIR}/SimGearTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/SimGearTargets.cmake")
+13
View File
@@ -0,0 +1,13 @@
Building a SimGear RPM package for Red Hat
Please see the "package/openSUSE" directory for an
example how to build a SimGear RPM package with
shared SimGear libraries.
You may need to adapt the names (exact spelling) of some
of the package dependencies in the openSUSE RPM spec,
since these may slightly differ for Red Hat.
(If you have a working and tested Red Hat RPM spec,
you're welcome to contribute it to this project.)
+23
View File
@@ -0,0 +1,23 @@
Building a SimGear RPM package for openSUSE
(Last tested with openSUSE 11.4+12.1)
This directory contains the files which, along with
the source code tar files, can be used to build
an RPM package targeted at an openSUSE Linux system.
To build SimGear from source do the following:
1. obtain simgear-2.8.0.tar.bz2 (adapt version if
necessary) and copy it into ~/rpmbuild/SOURCES
2. look in the BuildRequires section of SimGear.spec
and check that all the packages referred to are
installed (note, some of these packages may be part
of openSUSE's "games" repository).
3. run 'rpmbuild -ba simgear.spec' and find the RPM
build result in ~/rpmbuild/RPMS
That's all!
+63
View File
@@ -0,0 +1,63 @@
Summary: Simulator Construction Gear
Name: SimGear
Version: 2.8.0
Release: 1
License: LGPL
URL: http://www.flightgear.org
Group: Amusements/Games/3D/Simulation
Source: http://mirrors.ibiblio.org/pub/mirrors/flightgear/ftp/Source/simgear-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: gcc, gcc-c++, cmake
BuildRequires: libopenal1-soft, openal-soft
BuildRequires: libOpenSceneGraph-devel >= 3.0
BuildRequires: zlib, zlib-devel
BuildRequires: libjpeg62, libjpeg62-devel
BuildRequires: boost-devel >= 1.37
BuildRequires: subversion-devel, libapr1-devel
Requires: OpenSceneGraph-plugins >= 3.0
%description
This package contains a tools and libraries useful for constructing
simulation and visualization applications such as FlightGear or TerraGear.
%package devel
Group: Development/Libraries/Other
Summary: Development header files for SimGear
Requires: SimGear = %{version}
%description devel
Development headers and libraries for building applications against SimGear.
%prep
%setup -T -q -n simgear-%{version} -b 0
%build
export CFLAGS="$RPM_OPT_FLAGS"
export CXXFLAGS="$RPM_OPT_FLAGS"
# build SHARED simgear libraries
cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMGEAR_SHARED:BOOL=ON -DENABLE_TESTS:BOOL=OFF -DJPEG_FACTORY:BOOL=ON
make %{?_smp_mflags}
%install
make DESTDIR=%{buildroot} install
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr (-, root, root, -)
%doc AUTHORS COPYING ChangeLog NEWS README
%{_libdir}/libSimGear*.so.*
%files devel
%defattr(-,root,root,-)
%dir %{_includedir}/simgear
%{_includedir}/simgear/*
%{_libdir}/libSimGear*.so
%changelog
* Mon Jul 02 2012 thorstenb@flightgear.org
- Initial version
-1
View File
@@ -1 +0,0 @@
2020.3.9
+10 -36
View File
@@ -5,8 +5,6 @@ foreach( mylibfolder
bucket bucket
bvh bvh
debug debug
embedded_resources
emesary
ephemeris ephemeris
io io
magvar magvar
@@ -16,7 +14,6 @@ foreach( mylibfolder
nasal/cppbind nasal/cppbind
props props
serial serial
std
structure structure
threads threads
timing timing
@@ -65,9 +62,6 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION}) set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION}) set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
endif() endif()
export_debug_symbols(SimGearCore)
export_debug_symbols(SimGearScene)
else() else()
message(STATUS "Library building mode: STATIC LIBRARIES") message(STATUS "Library building mode: STATIC LIBRARIES")
@@ -118,22 +112,11 @@ target_include_directories(SimGearCore BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
# so simgear/simgear_config.h is found
target_include_directories(SimGearCore BEFORE PUBLIC
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>)
target_include_directories(SimGearCore PUBLIC target_include_directories(SimGearCore PUBLIC
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}) ${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
target_include_directories(SimGearCore PRIVATE target_include_directories(SimGearCore PRIVATE
${EXPAT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) ${EXPAT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS})
if (NOT SYSTEM_EXPAT)
# XML_STATIC is important to avoid sg_expat_external.h
# declaring symbols as declspec(import)
target_compile_definitions(SimGearCore PRIVATE HAVE_SIMGEAR_EXPAT_CONFIG_H XML_STATIC)
endif()
install(TARGETS SimGearCore install(TARGETS SimGearCore
EXPORT SimGearTargets EXPORT SimGearTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -158,46 +141,37 @@ if (NOT SIMGEAR_HEADLESS)
endif() endif()
endif() endif()
# we expose ZLib in some of our headers
target_link_libraries(SimGearCore PUBLIC ${ZLIB_LIBRARY})
target_link_libraries(SimGearCore PRIVATE target_link_libraries(SimGearCore
${ZLIB_LIBRARY}
${RT_LIBRARY} ${RT_LIBRARY}
${DL_LIBRARY} ${DL_LIBRARY}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${COCOA_LIBRARY} ${COCOA_LIBRARY}
${CURL_LIBRARIES} ${CURL_LIBRARIES}
${WINSOCK_LIBRARY} ${WINSOCK_LIBRARY})
${SHLWAPI_LIBRARY}
LibLZMA::LibLZMA
)
if(SYSTEM_EXPAT) if(SYSTEM_EXPAT)
target_link_libraries(SimGearCore PRIVATE ${EXPAT_LIBRARIES}) target_link_libraries(SimGearCore
${EXPAT_LIBRARIES})
endif() endif()
if(ENABLE_DNS AND SYSTEM_UDNS) if(ENABLE_DNS AND SYSTEM_UDNS)
target_link_libraries(SimGearCore PRIVATE ${UDNS_LIBRARIES}) target_link_libraries(SimGearCore
${UDNS_LIBRARIES})
endif() endif()
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include) target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
target_link_libraries(SimGearScene PUBLIC target_link_libraries(SimGearScene
SimGearCore SimGearCore
${OPENSCENEGRAPH_LIBRARIES}
)
target_link_libraries(SimGearScene PRIVATE
${ZLIB_LIBRARY} ${ZLIB_LIBRARY}
${OPENSCENEGRAPH_LIBRARIES}
${OPENAL_LIBRARY} ${OPENAL_LIBRARY}
${OPENGL_LIBRARY} ${OPENGL_LIBRARY}
${JPEG_LIBRARY}) ${JPEG_LIBRARY})
if(ENABLE_GDAL)
target_link_libraries(SimGearScene PRIVATE ${GDAL_LIBRARIES})
endif()
# only actually needed by canvas/KeyboardEvent.cxx # only actually needed by canvas/KeyboardEvent.cxx
target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/utf8/source) target_include_directories(SimGearScene PRIVATE ${PROJECT_SOURCE_DIR}/3rdparty/utf8/source)
endif() endif()
@@ -207,5 +181,5 @@ if(ENABLE_RTI)
set_property(SOURCE hla/RTI13InteractionClass.cxx hla/RTI13ObjectClass.cxx set_property(SOURCE hla/RTI13InteractionClass.cxx hla/RTI13ObjectClass.cxx
hla/RTI13ObjectInstance.cxx hla/RTI13Federate.cxx hla/RTI13ObjectInstance.cxx hla/RTI13Federate.cxx
hla/RTI13FederateFactory.cxx hla/RTI13FederateFactory.cxx
APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIRS}") APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
endif(ENABLE_RTI) endif(ENABLE_RTI)
+119 -198
View File
@@ -35,152 +35,124 @@ using std::endl;
void testBucketSpans() void testBucketSpans()
{ {
SG_CHECK_EQUAL(sg_bucket_span(0.0), 0.125); COMPARE(sg_bucket_span(0.0), 0.125);
SG_CHECK_EQUAL(sg_bucket_span(-20), 0.125); COMPARE(sg_bucket_span(-20), 0.125);
SG_CHECK_EQUAL(sg_bucket_span(-40), 0.25); COMPARE(sg_bucket_span(-40), 0.25);
SG_CHECK_EQUAL(sg_bucket_span(89.9), 12.0); COMPARE(sg_bucket_span(89.9), 12.0);
SG_CHECK_EQUAL(sg_bucket_span(88.1), 4.0); COMPARE(sg_bucket_span(88.1), 4.0);
SG_CHECK_EQUAL(sg_bucket_span(-89.9), 12.0); COMPARE(sg_bucket_span(-89.9), 12.0);
} }
void testBasic() void testBasic()
{ {
SGBucket b1(5.1, 55.05); SGBucket b1(5.1, 55.05);
SG_CHECK_EQUAL(b1.get_chunk_lon(), 5); COMPARE(b1.get_chunk_lon(), 5);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 55); COMPARE(b1.get_chunk_lat(), 55);
SG_CHECK_EQUAL(b1.get_x(), 0); COMPARE(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 0); COMPARE(b1.get_y(), 0);
SG_CHECK_EQUAL(b1.gen_index(), 3040320); COMPARE(b1.gen_index(), 3040320);
SG_CHECK_EQUAL(b1.gen_base_path(), "e000n50/e005n55"); COMPARE(b1.gen_base_path(), "e000n50/e005n55");
SG_VERIFY(b1.isValid()); VERIFY(b1.isValid());
SGBucket b2(-10.1, -43.8); SGBucket b2(-10.1, -43.8);
SG_CHECK_EQUAL(b2.get_chunk_lon(), -11); COMPARE(b2.get_chunk_lon(), -11);
SG_CHECK_EQUAL(b2.get_chunk_lat(), -44); COMPARE(b2.get_chunk_lat(), -44);
SG_CHECK_EQUAL(b2.get_x(), 3); COMPARE(b2.get_x(), 3);
// Latitude chunks numbered bottom to top, it seems COMPARE(b2.get_y(), 1); // latitude chunks numbered bottom to top, it seems
SG_CHECK_EQUAL(b2.get_y(), 1); COMPARE(b2.gen_base_path(), "w020s50/w011s44");
SG_CHECK_EQUAL(b2.gen_base_path(), "w020s50/w011s44"); VERIFY(b2.isValid());
SG_VERIFY(b2.isValid());
SGBucket b3(123.48, 9.01); SGBucket b3(123.48, 9.01);
SG_CHECK_EQUAL(b3.get_chunk_lon(), 123); COMPARE(b3.get_chunk_lon(), 123);
SG_CHECK_EQUAL(b3.get_chunk_lat(), 9); COMPARE(b3.get_chunk_lat(), 9);
SG_CHECK_EQUAL(b3.get_x(), 3); COMPARE(b3.get_x(), 3);
SG_CHECK_EQUAL(b3.get_y(), 0); COMPARE(b3.get_y(), 0);
SG_CHECK_EQUAL(b3.gen_base_path(), "e120n00/e123n09"); COMPARE(b3.gen_base_path(), "e120n00/e123n09");
SG_VERIFY(b3.isValid()); VERIFY(b3.isValid());
SGBucket defBuck; SGBucket defBuck;
SG_VERIFY(!defBuck.isValid()); VERIFY(!defBuck.isValid());
b3.make_bad(); b3.make_bad();
SG_VERIFY(!b3.isValid()); VERIFY(!b3.isValid());
SGBucket atAntiMeridian(180.0, 12.3); SGBucket atAntiMeridian(180.0, 12.3);
SG_VERIFY(atAntiMeridian.isValid()); VERIFY(atAntiMeridian.isValid());
SG_CHECK_EQUAL(atAntiMeridian.get_chunk_lon(), -180); COMPARE(atAntiMeridian.get_chunk_lon(), -180);
SG_CHECK_EQUAL(atAntiMeridian.get_x(), 0); COMPARE(atAntiMeridian.get_x(), 0);
SGBucket atAntiMeridian2(-180.0, -78.1); SGBucket atAntiMeridian2(-180.0, -78.1);
SG_VERIFY(atAntiMeridian2.isValid()); VERIFY(atAntiMeridian2.isValid());
SG_CHECK_EQUAL(atAntiMeridian2.get_chunk_lon(), -180); COMPARE(atAntiMeridian2.get_chunk_lon(), -180);
SG_CHECK_EQUAL(atAntiMeridian2.get_x(), 0); COMPARE(atAntiMeridian2.get_x(), 0);
// check comparison operator overload // check comparisom operator overload
SGBucket b4(5.11, 55.1); SGBucket b4(5.11, 55.1);
SG_VERIFY(b1 == b4); // should be equal VERIFY(b1 == b4); // should be equal
SG_VERIFY(b1 == b1); VERIFY(b1 == b1);
SG_VERIFY(b1 != defBuck); VERIFY(b1 != defBuck);
SG_VERIFY(b1 != b2); VERIFY(b1 != b2);
// check wrapping/clipping of inputs // check wrapping/clipping of inputs
SGBucket wrapMeridian(-200.0, 45.0); SGBucket wrapMeridian(-200.0, 45.0);
SG_CHECK_EQUAL(wrapMeridian.get_chunk_lon(), 160); COMPARE(wrapMeridian.get_chunk_lon(), 160);
SGBucket clipPole(48.9, 91); SGBucket clipPole(48.9, 91);
SG_CHECK_EQUAL(clipPole.get_chunk_lat(), 89); COMPARE(clipPole.get_chunk_lat(), 89);
// test override of a bucket's geod
auto geod = SGGeod::fromDegFt(-86.678, 36.1248, 599.0);
#ifndef NO_DEPRECATED_API
SGBucket bna_airport;
bna_airport.set_bucket(geod);
#else
SGBucket bna_airport(geod);
#endif
SG_VERIFY(bna_airport.isValid());
SG_CHECK_EQUAL(bna_airport.get_chunk_lon(), -87); // left origin of the 1-degree chunk
SG_CHECK_EQUAL(bna_airport.get_chunk_lat(), 36); // bottom origin of the 1-degree chunk
SG_CHECK_EQUAL(bna_airport.get_x(), 1); // buckets are 0.25 deg wide at the W87 parallel
// we're 0.322 deg from the origin (second bucket)
SG_CHECK_EQUAL(bna_airport.get_y(), 0); // buckets are always 0.125 deg tall
// we're 0.1248 deg from the origin (first bucket)
SG_CHECK_EQUAL(bna_airport.gen_base_path(), "w090n30/w087n36");
SG_CHECK_EQUAL_EP2(bna_airport.get_width_m(), 22479.1, 0.1);
SG_CHECK_EQUAL_EP2(bna_airport.get_height_m(), 13914.9, 0.1);
SG_CHECK_EQUAL(bna_airport.gen_index_str(), "1531777"); // 0x175F81 = b01011101|01111110|000|001
// = 93-180 | 126-90 | 0 | 1
// = -87 | 36 | 0 | 1
// test stream output
cout << "[TEST] BNA Airport: " << bna_airport << endl;
auto center = bna_airport.get_center();
cout << "[TEST] BNA lon: " << center.getLongitudeDeg() << endl;
cout << "[TEST] BNA lat: " << center.getLatitudeDeg() << endl;
} }
void testPolar() void testPolar()
{ {
SGBucket b1(0.0, 89.92); SGBucket b1(0.0, 89.92);
SGBucket b2(10.0, 89.96); SGBucket b2(10.0, 89.96);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 89); COMPARE(b1.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b1.get_chunk_lon(), 0); COMPARE(b1.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b1.get_x(), 0); COMPARE(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 7); COMPARE(b1.get_y(), 7);
SG_CHECK_EQUAL_EP(b1.get_highest_lat(), 90.0); COMPARE_EP(b1.get_highest_lat(), 90.0);
SG_CHECK_EQUAL_EP(b1.get_width_m(), 10.0); COMPARE_EP(b1.get_width_m(), 10.0);
SG_CHECK_EQUAL(b2.get_chunk_lat(), 89); COMPARE(b2.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b2.get_chunk_lon(), 0); COMPARE(b2.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b2.get_x(), 0); COMPARE(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 7); COMPARE(b2.get_y(), 7);
SG_CHECK_EQUAL(b1.gen_index(), b2.gen_index()); COMPARE(b1.gen_index(), b2.gen_index());
SGGeod actualNorthPole1 = b1.get_corner(2); SGGeod actualNorthPole1 = b1.get_corner(2);
SGGeod actualNorthPole2 = b1.get_corner(3); SGGeod actualNorthPole2 = b1.get_corner(3);
SG_CHECK_EQUAL_EP(actualNorthPole1.getLatitudeDeg(), 90.0); COMPARE_EP(actualNorthPole1.getLatitudeDeg(), 90.0);
SG_CHECK_EQUAL_EP(actualNorthPole1.getLongitudeDeg(), 12.0); COMPARE_EP(actualNorthPole1.getLongitudeDeg(), 12.0);
SG_CHECK_EQUAL_EP(actualNorthPole2.getLatitudeDeg(), 90.0); COMPARE_EP(actualNorthPole2.getLatitudeDeg(), 90.0);
SG_CHECK_EQUAL_EP(actualNorthPole2.getLongitudeDeg(), 0.0); COMPARE_EP(actualNorthPole2.getLongitudeDeg(), 0.0);
SGBucket b3(-2, 89.88); SGBucket b3(-2, 89.88);
SGBucket b4(-7, 89.88); SGBucket b4(-7, 89.88);
SG_CHECK_EQUAL(b3.gen_index(), b4.gen_index()); COMPARE(b3.gen_index(), b4.gen_index());
// south pole // south pole
SGBucket b5(-170, -89.88); SGBucket b5(-170, -89.88);
SGBucket b6(-179, -89.88); SGBucket b6(-179, -89.88);
SG_CHECK_EQUAL(b5.get_chunk_lat(), -90); COMPARE(b5.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b5.get_chunk_lon(), -180); COMPARE(b5.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b5.get_x(), 0); COMPARE(b5.get_x(), 0);
SG_CHECK_EQUAL(b5.get_y(), 0); COMPARE(b5.get_y(), 0);
SG_CHECK_EQUAL(b5.gen_index(), b6.gen_index()); COMPARE(b5.gen_index(), b6.gen_index());
SG_CHECK_EQUAL_EP(b5.get_highest_lat(), -90.0); COMPARE_EP(b5.get_highest_lat(), -90.0);
SG_CHECK_EQUAL_EP(b5.get_width_m(), 10.0); COMPARE_EP(b5.get_width_m(), 10.0);
SGGeod actualSouthPole1 = b5.get_corner(0); SGGeod actualSouthPole1 = b5.get_corner(0);
SGGeod actualSouthPole2 = b5.get_corner(1); SGGeod actualSouthPole2 = b5.get_corner(1);
SG_CHECK_EQUAL_EP(actualSouthPole1.getLatitudeDeg(), -90.0); COMPARE_EP(actualSouthPole1.getLatitudeDeg(), -90.0);
SG_CHECK_EQUAL_EP(actualSouthPole1.getLongitudeDeg(), -180); COMPARE_EP(actualSouthPole1.getLongitudeDeg(), -180);
SG_CHECK_EQUAL_EP(actualSouthPole2.getLatitudeDeg(), -90.0); COMPARE_EP(actualSouthPole2.getLatitudeDeg(), -90.0);
SG_CHECK_EQUAL_EP(actualSouthPole2.getLongitudeDeg(), -168); COMPARE_EP(actualSouthPole2.getLongitudeDeg(), -168);
SGBucket b7(200, 89.88); SGBucket b7(200, 89.88);
SG_CHECK_EQUAL(b7.get_chunk_lon(), -168); COMPARE(b7.get_chunk_lon(), -168);
} }
// test the tiles just below the pole (between 86 & 89 degrees N/S) // test the tiles just below the pole (between 86 & 89 degrees N/S)
@@ -188,15 +160,15 @@ void testNearPolar()
{ {
SGBucket b1(1, 88.5); SGBucket b1(1, 88.5);
SGBucket b2(-1, 88.8); SGBucket b2(-1, 88.8);
SG_CHECK_EQUAL(b1.get_chunk_lon(), 0); COMPARE(b1.get_chunk_lon(), 0);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 88); COMPARE(b1.get_chunk_lat(), 88);
SG_VERIFY(b1.gen_index() != b2.gen_index()); VERIFY(b1.gen_index() != b2.gen_index());
SGBucket b3(176.1, 88.5); SGBucket b3(176.1, 88.5);
SG_CHECK_EQUAL(b3.get_chunk_lon(), 176); COMPARE(b3.get_chunk_lon(), 176);
SGBucket b4(-178, 88.5); SGBucket b4(-178, 88.5);
SG_CHECK_EQUAL(b4.get_chunk_lon(), -180); COMPARE(b4.get_chunk_lon(), -180);
} }
void testOffset() void testOffset()
@@ -204,74 +176,74 @@ void testOffset()
// bucket just below the 22 degree cutoff, so the next tile north // bucket just below the 22 degree cutoff, so the next tile north
// is twice the width // is twice the width
SGBucket b1(-59.8, 21.9); SGBucket b1(-59.8, 21.9);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 21); COMPARE(b1.get_chunk_lat(), 21);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -60); COMPARE(b1.get_chunk_lon(), -60);
SG_CHECK_EQUAL(b1.get_x(), 1); COMPARE(b1.get_x(), 1);
SG_CHECK_EQUAL(b1.get_y(), 7); COMPARE(b1.get_y(), 7);
// offset vertically // offset vertically
SGBucket b2(b1.sibling(0, 1)); SGBucket b2(b1.sibling(0, 1));
SG_CHECK_EQUAL(b2.get_chunk_lat(), 22); COMPARE(b2.get_chunk_lat(), 22);
SG_CHECK_EQUAL(b2.get_chunk_lon(), -60); COMPARE(b2.get_chunk_lon(), -60);
SG_CHECK_EQUAL(b2.get_x(), 0); COMPARE(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 0); COMPARE(b2.get_y(), 0);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-59.8, 21.9, 0, 1)); COMPARE(b2.gen_index(), sgBucketOffset(-59.8, 21.9, 0, 1));
// offset vertically and horizontally. We compute horizontal (x) // offset vertically and horizontally. We compute horizontal (x)
// movement at the target latitude, so this should move 0.25 * -3 degrees, // movement at the target latitude, so this should move 0.25 * -3 degrees,
// NOT 0.125 * -3 degrees. // NOT 0.125 * -3 degrees.
SGBucket b3(b1.sibling(-3, 1)); SGBucket b3(b1.sibling(-3, 1));
SG_CHECK_EQUAL(b3.get_chunk_lat(), 22); COMPARE(b3.get_chunk_lat(), 22);
SG_CHECK_EQUAL(b3.get_chunk_lon(), -61); COMPARE(b3.get_chunk_lon(), -61);
SG_CHECK_EQUAL(b3.get_x(), 1); COMPARE(b3.get_x(), 1);
SG_CHECK_EQUAL(b3.get_y(), 0); COMPARE(b3.get_y(), 0);
SG_CHECK_EQUAL(b3.gen_index(), sgBucketOffset(-59.8, 21.9, -3, 1)); COMPARE(b3.gen_index(), sgBucketOffset(-59.8, 21.9, -3, 1));
} }
void testPolarOffset() void testPolarOffset()
{ {
SGBucket b1(-11.7, -89.6); SGBucket b1(-11.7, -89.6);
SG_CHECK_EQUAL(b1.get_chunk_lat(), -90); COMPARE(b1.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -12); COMPARE(b1.get_chunk_lon(), -12);
SG_CHECK_EQUAL(b1.get_x(), 0); COMPARE(b1.get_x(), 0);
SG_CHECK_EQUAL(b1.get_y(), 3); COMPARE(b1.get_y(), 3);
// offset horizontally // offset horizontally
SGBucket b2(b1.sibling(-2, 0)); SGBucket b2(b1.sibling(-2, 0));
SG_CHECK_EQUAL(b2.get_chunk_lat(), -90); COMPARE(b2.get_chunk_lat(), -90);
SG_CHECK_EQUAL(b2.get_chunk_lon(), -36); COMPARE(b2.get_chunk_lon(), -36);
SG_CHECK_EQUAL(b2.get_x(), 0); COMPARE(b2.get_x(), 0);
SG_CHECK_EQUAL(b2.get_y(), 3); COMPARE(b2.get_y(), 3);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-11.7, -89.6, -2, 0)); COMPARE(b2.gen_index(), sgBucketOffset(-11.7, -89.6, -2, 0));
// offset and wrap // offset and wrap
SGBucket b3(-170, 89.1); SGBucket b3(-170, 89.1);
SGBucket b4(b3.sibling(-1, 0)); SGBucket b4(b3.sibling(-1, 0));
SG_CHECK_EQUAL(b4.get_chunk_lat(), 89); COMPARE(b4.get_chunk_lat(), 89);
SG_CHECK_EQUAL(b4.get_chunk_lon(), 168); COMPARE(b4.get_chunk_lon(), 168);
SG_CHECK_EQUAL(b4.get_x(), 0); COMPARE(b4.get_x(), 0);
SG_CHECK_EQUAL(b4.get_y(), 0); COMPARE(b4.get_y(), 0);
SG_CHECK_EQUAL(b4.gen_index(), sgBucketOffset(-170, 89.1, -1, 0)); COMPARE(b4.gen_index(), sgBucketOffset(-170, 89.1, -1, 0));
SGBucket b5(177, 87.3); SGBucket b5(177, 87.3);
SGBucket b6(b5.sibling(1, 1)); SGBucket b6(b5.sibling(1, 1));
SG_CHECK_EQUAL(b6.get_chunk_lat(), 87); COMPARE(b6.get_chunk_lat(), 87);
SG_CHECK_EQUAL(b6.get_chunk_lon(), -180); COMPARE(b6.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b6.get_x(), 0); COMPARE(b6.get_x(), 0);
SG_CHECK_EQUAL(b6.get_y(), 3); COMPARE(b6.get_y(), 3);
SG_CHECK_EQUAL(b6.gen_index(), sgBucketOffset(177, 87.3, 1, 1)); COMPARE(b6.gen_index(), sgBucketOffset(177, 87.3, 1, 1));
// offset vertically towards the pole // offset vertically towards the pole
SGBucket b7(b1.sibling(0, -5)); SGBucket b7(b1.sibling(0, -5));
SG_VERIFY(!b7.isValid()); VERIFY(!b7.isValid());
SG_VERIFY(!SGBucket(0, 90).sibling(0, 1).isValid()); VERIFY(!SGBucket(0, 90).sibling(0, 1).isValid());
} }
// test behaviour of bucket-offset near the anti-meridian (180-meridian) // test behaviour of bucket-offset near the anti-meridian (180-meridian)
@@ -279,70 +251,19 @@ void testOffsetWrap()
{ {
// near the equator // near the equator
SGBucket b1(-179.8, 16.8); SGBucket b1(-179.8, 16.8);
SG_CHECK_EQUAL(b1.get_chunk_lat(), 16); COMPARE(b1.get_chunk_lat(), 16);
SG_CHECK_EQUAL(b1.get_chunk_lon(), -180); COMPARE(b1.get_chunk_lon(), -180);
SG_CHECK_EQUAL(b1.get_x(), 1); COMPARE(b1.get_x(), 1);
SG_CHECK_EQUAL(b1.get_y(), 6); COMPARE(b1.get_y(), 6);
SGBucket b2(b1.sibling(-2, 0)); SGBucket b2(b1.sibling(-2, 0));
SG_CHECK_EQUAL(b2.get_chunk_lat(), 16); COMPARE(b2.get_chunk_lat(), 16);
SG_CHECK_EQUAL(b2.get_chunk_lon(), 179); COMPARE(b2.get_chunk_lon(), 179);
SG_CHECK_EQUAL(b2.get_x(), 7); COMPARE(b2.get_x(), 7);
SG_CHECK_EQUAL(b2.get_y(), 6); COMPARE(b2.get_y(), 6);
SG_CHECK_EQUAL(b2.gen_index(), sgBucketOffset(-179.8, 16.8, -2, 0)); COMPARE(b2.gen_index(), sgBucketOffset(-179.8, 16.8, -2, 0));
}
void testSiblings()
{
SGBucket bna_airport(-86.678, 36.1248);
SG_VERIFY(bna_airport.isValid());
// retrieve the sibling two positions north-east of my position
auto sib1 = bna_airport.sibling(2, 2);
SG_CHECK_EQUAL(sib1.get_chunk_lon(), bna_airport.get_chunk_lon());
SG_CHECK_EQUAL(sib1.get_chunk_lat(), bna_airport.get_chunk_lat());
SG_CHECK_EQUAL(sib1.get_x(), 3); // my x-pos (1) + 2 = 3
SG_CHECK_EQUAL(sib1.get_y(), 2); // my y-pos (0) + 2 = 2
SG_CHECK_EQUAL(sib1.gen_base_path(), bna_airport.gen_base_path());
// retrieve the one sibling two positions to the north-east
std::vector<SGBucket> siblings;
bna_airport.siblings(2, 2, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(1));
siblings.clear();
// retrieve the one sibling at the chunk origin of sib1
sib1.siblings(-2, -2, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(1));
siblings.clear();
// calculate delta between two buckets
int dx = 0;
int dy = 0;
sgBucketDiff(bna_airport, sib1, &dx, &dy);
SG_CHECK_EQUAL(dx, 2);
SG_CHECK_EQUAL(dy, 2);
// retrieve all siblings between two geodetic locations
auto geod_bna = SGGeod::fromDegFt(-86.678, 36.1248, 599.0);
auto geod_m54 = SGGeod::fromDegFt(-86.317, 36.1908, 122.0);
sgGetBuckets(geod_bna, geod_m54, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(4));
siblings.clear();
// edge cases
// ensure you cannot retrieve the sibling of an invalid bucket
SGBucket bad;
auto bad_sib = bad.sibling(1, 1);
SG_CHECK_EQUAL(bad_sib.get_chunk_lon(), -1000);
SG_CHECK_EQUAL(bad.siblings(2, 2, siblings), 0);
// if we drop below the 22nd parallel, the bucket widths are half the size
// expect this to retrieve two buckets
bna_airport.siblings(0, -160, siblings);
SG_CHECK_EQUAL(siblings.size(), static_cast<std::vector<SGBucket>::size_type>(2));
siblings.clear();
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@@ -355,8 +276,8 @@ int main(int argc, char* argv[])
testOffset(); testOffset();
testOffsetWrap(); testOffsetWrap();
testPolarOffset(); testPolarOffset();
testSiblings();
cout << "all tests passed OK" << endl; cout << "all tests passed OK" << endl;
return 0; // passed return 0; // passed
} }
-2
View File
@@ -15,8 +15,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include "BVHMaterial.hxx" #include "BVHMaterial.hxx"
namespace simgear { namespace simgear {
-2
View File
@@ -15,8 +15,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include "BVHPageNode.hxx" #include "BVHPageNode.hxx"
#include "BVHPager.hxx" #include "BVHPager.hxx"
-2
View File
@@ -15,8 +15,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include "BVHPageRequest.hxx" #include "BVHPageRequest.hxx"
namespace simgear { namespace simgear {
+7 -9
View File
@@ -15,14 +15,12 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include "BVHPager.hxx" #include "BVHPager.hxx"
#include <list> #include <list>
#include <mutex>
#include <simgear/threads/SGThread.hxx> #include <simgear/threads/SGThread.hxx>
#include <simgear/threads/SGGuard.hxx>
#include "BVHPageNode.hxx" #include "BVHPageNode.hxx"
#include "BVHPageRequest.hxx" #include "BVHPageRequest.hxx"
@@ -37,12 +35,12 @@ struct BVHPager::_PrivateData : protected SGThread {
struct _LockedQueue { struct _LockedQueue {
void _push(const _Request& request) void _push(const _Request& request)
{ {
std::lock_guard<std::mutex> scopeLock(_mutex); SGGuard<SGMutex> scopeLock(_mutex);
_requestList.push_back(request); _requestList.push_back(request);
} }
_Request _pop() _Request _pop()
{ {
std::lock_guard<std::mutex> scopeLock(_mutex); SGGuard<SGMutex> scopeLock(_mutex);
if (_requestList.empty()) if (_requestList.empty())
return _Request(); return _Request();
_Request request; _Request request;
@@ -51,7 +49,7 @@ struct BVHPager::_PrivateData : protected SGThread {
return request; return request;
} }
private: private:
std::mutex _mutex; SGMutex _mutex;
_RequestList _requestList; _RequestList _requestList;
}; };
@@ -62,7 +60,7 @@ struct BVHPager::_PrivateData : protected SGThread {
} }
void _push(const _Request& request) void _push(const _Request& request)
{ {
std::lock_guard<std::mutex> scopeLock(_mutex); SGGuard<SGMutex> scopeLock(_mutex);
bool needSignal = _requestList.empty(); bool needSignal = _requestList.empty();
_requestList.push_back(request); _requestList.push_back(request);
if (needSignal) if (needSignal)
@@ -70,7 +68,7 @@ struct BVHPager::_PrivateData : protected SGThread {
} }
_Request _pop() _Request _pop()
{ {
std::lock_guard<std::mutex> scopeLock(_mutex); SGGuard<SGMutex> scopeLock(_mutex);
while (_requestList.empty()) while (_requestList.empty())
_waitCondition.wait(_mutex); _waitCondition.wait(_mutex);
_Request request; _Request request;
@@ -79,7 +77,7 @@ struct BVHPager::_PrivateData : protected SGThread {
return request; return request;
} }
private: private:
std::mutex _mutex; SGMutex _mutex;
SGWaitCondition _waitCondition; SGWaitCondition _waitCondition;
_RequestList _requestList; _RequestList _requestList;
}; };
-2
View File
@@ -15,8 +15,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include "BVHStaticNode.hxx" #include "BVHStaticNode.hxx"
namespace simgear { namespace simgear {
-1
View File
@@ -15,7 +15,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include <simgear_config.h>
#include <iostream> #include <iostream>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
+20 -140
View File
@@ -1,5 +1,4 @@
///@file // The canvas for rendering with the 2d API
/// The canvas for rendering with the 2d API
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,16 +16,12 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "Canvas.hxx" #include "Canvas.hxx"
#include "CanvasEventManager.hxx" #include "CanvasEventManager.hxx"
#include "CanvasEventVisitor.hxx" #include "CanvasEventVisitor.hxx"
#include "CanvasPlacement.hxx" #include "CanvasPlacement.hxx"
#include <simgear/canvas/events/KeyboardEvent.hxx> #include <simgear/canvas/events/KeyboardEvent.hxx>
#include <simgear/canvas/events/MouseEvent.hxx> #include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/scene/util/parse_color.hxx> #include <simgear/scene/util/parse_color.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>
@@ -35,79 +30,13 @@
#include <osgText/Text> #include <osgText/Text>
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
namespace simgear namespace simgear
{ {
namespace canvas namespace canvas
{ {
static int globalinstanceid = 1;
/**
* Camera Callback for moving completed canvas images to subscribed listener.
*/
class CanvasImageCallback : public osg::Camera::DrawCallback {
public:
osg::Image *_rawImage;
CanvasImageCallback(osg::Image *rawImage)
: _min_delta_tick(1.0 / 8.0) {
_previousFrameTick = osg::Timer::instance()->tick();
_rawImage = rawImage;
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImageCallback created. instance is " << instanceid);
}
virtual void operator()(osg::RenderInfo& renderInfo) const {
osg::Timer_t n = osg::Timer::instance()->tick();
double dt = osg::Timer::instance()->delta_s(_previousFrameTick, n);
if (dt < _min_delta_tick)
return;
_previousFrameTick = n;
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImageCallback " << instanceid << ": image available for " << _subscribers.size() << " subscribers. camera is " << renderInfo.getCurrentCamera());
bool hasSubscribers = false;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
hasSubscribers = !_subscribers.empty();
}
if (hasSubscribers) {
//Make sure image can be overwritten by next frame while it is still returned to the client
osg::Image* image = new osg::Image(*_rawImage, osg::CopyOp::DEEP_COPY_ALL);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
while (!_subscribers.empty()) {
try {
CanvasImageReadyListener *subs = _subscribers.back();
if (subs){
subs->imageReady(image);
}else{
SG_LOG(SG_GENERAL,SG_WARN,"CanvasImageCallback subscriber null");
}
} catch (...) { }
_subscribers.pop_back();
}
}
}
}
void subscribe(CanvasImageReadyListener * subscriber) {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
_subscribers.push_back(subscriber);
}
void unsubscribe(CanvasImageReadyListener * subscriber) {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lock);
_subscribers.remove(subscriber);
}
int getSubscriberCount() {
return _subscribers.size();
}
private:
mutable list<CanvasImageReadyListener*> _subscribers;
mutable OpenThreads::Mutex _lock;
mutable double _previousFrameTick;
double _min_delta_tick;
int instanceid = globalinstanceid++;
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Canvas::CullCallback::CullCallback(const CanvasWeakPtr& canvas): Canvas::CullCallback::CullCallback(const CanvasWeakPtr& canvas):
@@ -133,9 +62,18 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Canvas::Canvas(SGPropertyNode* node): Canvas::Canvas(SGPropertyNode* node):
PropertyBasedElement(node), PropertyBasedElement(node),
_canvas_mgr(0),
_event_manager(new EventManager), _event_manager(new EventManager),
_size_x(-1),
_size_y(-1),
_view_width(-1),
_view_height(-1),
_status(node, "status"), _status(node, "status"),
_status_msg(node, "status-msg") _status_msg(node, "status-msg"),
_sampling_dirty(false),
_render_dirty(true),
_visible(true),
_render_always(false)
{ {
_status = 0; _status = 0;
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y); setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
@@ -296,10 +234,6 @@ namespace canvas
if( _status & STATUS_DIRTY ) if( _status & STATUS_DIRTY )
{ {
// Retrieve reference here, to ensure the scene group is not deleted while
// creating the new texture and camera
osg::ref_ptr<osg::Group> root_scene_group = _root_group->getSceneGroup();
_texture.setSize(_size_x, _size_y); _texture.setSize(_size_x, _size_y);
if( !_texture.serviceable() ) if( !_texture.serviceable() )
@@ -317,21 +251,6 @@ namespace canvas
osg::Camera* camera = _texture.getCamera(); osg::Camera* camera = _texture.getCamera();
string canvasname = _node->getStringValue("name");
int renderToImage = _node->getBoolValue("render-to-image");
if (renderToImage){
CanvasImageCallback *_screenshotCallback = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (!_screenshotCallback) {
// no draw callback yet
osg::Image* shot = new osg::Image();
shot->allocateImage(getSizeX(), getSizeY(), 24, GL_RGB, GL_UNSIGNED_BYTE);
camera->attach(osg::Camera::COLOR_BUFFER, shot);
camera->setFinalDrawCallback(new CanvasImageCallback(shot));
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImage: attached image and draw callback to camera " << camera << " for canvas " << canvasname << ". Ready for subscriber now.");
}
}
// TODO Allow custom render order? For now just keep in order with // TODO Allow custom render order? For now just keep in order with
// property tree. // property tree.
camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex()); camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex());
@@ -340,7 +259,7 @@ namespace canvas
parseColor(_node->getStringValue("background"), clear_color); parseColor(_node->getStringValue("background"), clear_color);
camera->setClearColor(clear_color); camera->setClearColor(clear_color);
camera->addChild(root_scene_group); camera->addChild(_root_group->getMatrixTransform());
if( _texture.serviceable() ) if( _texture.serviceable() )
{ {
@@ -360,7 +279,7 @@ namespace canvas
if( _visible || _render_always ) if( _visible || _render_always )
{ {
for(auto& canvas_weak: _child_canvases) BOOST_FOREACH(CanvasWeakPtr canvas_weak, _child_canvases)
{ {
// TODO should we check if the image the child canvas is displayed // TODO should we check if the image the child canvas is displayed
// within is really visible? // within is really visible?
@@ -372,7 +291,7 @@ namespace canvas
if( _render_dirty ) if( _render_dirty )
{ {
// Also mark all canvases this canvas is displayed within as dirty // Also mark all canvases this canvas is displayed within as dirty
for(auto& canvas_weak: _parent_canvases) BOOST_FOREACH(CanvasWeakPtr canvas_weak, _parent_canvases)
{ {
CanvasPtr canvas = canvas_weak.lock(); CanvasPtr canvas = canvas_weak.lock();
if( canvas ) if( canvas )
@@ -431,41 +350,6 @@ namespace canvas
} }
} }
int Canvas::subscribe(CanvasImageReadyListener * subscriber) {
osg::Camera* camera = _texture.getCamera();
const string canvasname = _node->getStringValue("name");
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: subscribe to canvas " << canvasname.c_str() << ", camera ="<< camera);
if (!_node->getBoolValue("render-to-image")) {
SG_LOG(SG_GENERAL,SG_INFO,"CanvasImage: Setting render-to-image");
_node->addChild("render-to-image", 0)->setBoolValue(1);
setStatusFlags(STATUS_DIRTY, true);
}
CanvasImageCallback *_screenshotCallback = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (_screenshotCallback) {
// Camera ready for subscriber. Otherwise, draw callback is created by canvas thread later.
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: adding subscriber to camera draw callback");
_screenshotCallback->subscribe(subscriber);
// TODO: check: Is this the correct way to ensure the canvas will be available?
enableRendering(true);
return 1;
}
return 0;
}
int Canvas::unsubscribe(CanvasImageReadyListener * subscriber) {
osg::Camera* camera = _texture.getCamera();
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: unsubscribe");
CanvasImageCallback *cb = dynamic_cast<CanvasImageCallback*> (camera->getFinalDrawCallback());
if (cb) {
SG_LOG(SG_GENERAL,SG_DEBUG,"CanvasImage: unsubscribe from camera " << camera);
cb->unsubscribe(subscriber);
}
return 0;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Canvas::addEventListener( const std::string& type, bool Canvas::addEventListener( const std::string& type,
const EventListener& cb ) const EventListener& cb )
@@ -636,8 +520,8 @@ namespace canvas
{ {
const std::string& name = node->getNameString(); const std::string& name = node->getNameString();
if( strutils::starts_with(name, "status") if( boost::starts_with(name, "status")
|| strutils::starts_with(name, "data-") ) || boost::starts_with(name, "data-") )
return; return;
_render_dirty = true; _render_dirty = true;
@@ -652,7 +536,7 @@ namespace canvas
if( !placements.empty() ) if( !placements.empty() )
{ {
bool placement_dirty = false; bool placement_dirty = false;
for(auto& placement: placements) BOOST_FOREACH(PlacementPtr& placement, placements)
{ {
// check if change can be directly handled by placement // check if change can be directly handled by placement
if( placement->getProps() == node->getParent() if( placement->getProps() == node->getParent()
@@ -691,10 +575,6 @@ namespace canvas
{ {
_sampling_dirty = true; _sampling_dirty = true;
} }
else if( name == "anisotropy" )
{
_texture.setMaxAnisotropy( node->getFloatValue() );
}
else if( name == "additive-blend" ) else if( name == "additive-blend" )
{ {
_texture.useAdditiveBlend( node->getBoolValue() ); _texture.useAdditiveBlend( node->getBoolValue() );
+23 -39
View File
@@ -33,7 +33,7 @@
#include <osg/NodeCallback> #include <osg/NodeCallback>
#include <osg/observer_ptr> #include <osg/observer_ptr>
#include <memory> #include <boost/scoped_ptr.hpp>
#include <string> #include <string>
namespace simgear namespace simgear
@@ -44,17 +44,6 @@ namespace canvas
class CanvasMgr; class CanvasMgr;
class MouseEvent; class MouseEvent;
/**
* A listener interested in completed canvas drawing.
*/
class CanvasImageReadyListener {
public:
virtual void imageReady(osg::ref_ptr<osg::Image>) = 0;
virtual ~CanvasImageReadyListener()
{
}
};
/** /**
* Canvas to draw onto (to an off-screen render target). * Canvas to draw onto (to an off-screen render target).
*/ */
@@ -82,18 +71,18 @@ namespace canvas
public osg::NodeCallback public osg::NodeCallback
{ {
public: public:
explicit CullCallback(const CanvasWeakPtr& canvas); CullCallback(const CanvasWeakPtr& canvas);
private: private:
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
void operator()(osg::Node* node, osg::NodeVisitor* nv) override; virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
}; };
typedef osg::ref_ptr<CullCallback> CullCallbackPtr; typedef osg::ref_ptr<CullCallback> CullCallbackPtr;
explicit Canvas(SGPropertyNode* node); Canvas(SGPropertyNode* node);
virtual ~Canvas(); virtual ~Canvas();
void onDestroy() override; virtual void onDestroy();
void setCanvasMgr(CanvasMgr* canvas_mgr); void setCanvasMgr(CanvasMgr* canvas_mgr);
CanvasMgr* getCanvasMgr() const; CanvasMgr* getCanvasMgr() const;
@@ -171,12 +160,7 @@ namespace canvas
*/ */
void enableRendering(bool force = false); void enableRendering(bool force = false);
void update(double delta_time_sec) override; void update(double delta_time_sec);
osg::Camera* getCamera();
int subscribe(CanvasImageReadyListener * subscriber);
int unsubscribe(CanvasImageReadyListener * subscriber);
int getSubscriberCount();
bool addEventListener(const std::string& type, const EventListener& cb); bool addEventListener(const std::string& type, const EventListener& cb);
bool dispatchEvent(const EventPtr& event); bool dispatchEvent(const EventPtr& event);
@@ -200,9 +184,11 @@ namespace canvas
bool propagateEvent( EventPtr const& event, bool propagateEvent( EventPtr const& event,
EventPropagationPath const& path ); EventPropagationPath const& path );
void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override; virtual void childAdded( SGPropertyNode * parent,
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override; SGPropertyNode * child );
void valueChanged(SGPropertyNode * node) override; virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged (SGPropertyNode * node);
osg::Texture2D* getTexture() const; osg::Texture2D* getTexture() const;
@@ -225,21 +211,21 @@ namespace canvas
protected: protected:
CanvasMgr *_canvas_mgr {nullptr}; CanvasMgr *_canvas_mgr;
std::unique_ptr<EventManager> _event_manager; boost::scoped_ptr<EventManager> _event_manager;
int _size_x {-1}, int _size_x,
_size_y {-1}, _size_y,
_view_width {-1}, _view_width,
_view_height {-1}; _view_height;
PropertyObject<int> _status; PropertyObject<int> _status;
PropertyObject<std::string> _status_msg; PropertyObject<std::string> _status_msg;
bool _sampling_dirty {false}, bool _sampling_dirty,
_render_dirty {true}, _render_dirty,
_visible {true}; _visible;
ODGauge _texture; ODGauge _texture;
@@ -249,9 +235,7 @@ namespace canvas
ElementWeakPtr _focus_element; ElementWeakPtr _focus_element;
CullCallbackPtr _cull_callback; CullCallbackPtr _cull_callback;
bool _render_always; //!< Used to disable automatic lazy rendering (culling)
/** Used to disable automatic lazy rendering (culling) */
bool _render_always {false};
std::vector<SGPropertyNode*> _dirty_placements; std::vector<SGPropertyNode*> _dirty_placements;
std::vector<Placements> _placements; std::vector<Placements> _placements;
@@ -268,8 +252,8 @@ namespace canvas
static SystemAdapterPtr _system_adapter; static SystemAdapterPtr _system_adapter;
Canvas(const Canvas&) = delete; Canvas(const Canvas&); // = delete;
Canvas& operator=(const Canvas&) = delete; Canvas& operator=(const Canvas&); // = delete;
}; };
} // namespace canvas } // namespace canvas
+4 -7
View File
@@ -1,5 +1,4 @@
///@file // Canvas Event for event model similar to DOM Level 3 Event Model
/// Canvas Event for event model similar to DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEvent.hxx" #include "CanvasEvent.hxx"
namespace simgear namespace simgear
@@ -126,10 +123,10 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string Event::typeToStr(int type) std::string Event::typeToStr(int type)
{ {
auto const& map_by_id = getTypeMap().by<id>(); TypeMap const& type_map = getTypeMap();
auto it = map_by_id.find(type); TypeMap::map_by<id>::const_iterator it = type_map.by<id>().find(type);
if( it == map_by_id.end() ) if( it == type_map.by<id>().end() )
return "unknown"; return "unknown";
return it->second; return it->second;
} }
-12
View File
@@ -65,11 +65,6 @@ namespace canvas
// of the actual event instances. // of the actual event instances.
virtual ~Event(); virtual ~Event();
/**
* Clone event and set to the given type (Same type if not specified)
*/
virtual Event* clone(int type = 0) const = 0;
/** /**
* Get whether this events support bubbling * Get whether this events support bubbling
*/ */
@@ -115,14 +110,7 @@ namespace canvas
*/ */
bool defaultPrevented() const; bool defaultPrevented() const;
/**
* Register a new type string or get the id of an existing type string
*
* @param type Type string
* @return Id of the given @a type
*/
static int getOrRegisterType(const std::string& type); static int getOrRegisterType(const std::string& type);
static int strToType(const std::string& type); static int strToType(const std::string& type);
static std::string typeToStr(int type); static std::string typeToStr(int type);
+3 -9
View File
@@ -1,5 +1,4 @@
///@file // Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,12 +16,9 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEventManager.hxx" #include "CanvasEventManager.hxx"
#include "elements/CanvasElement.hxx" #include <simgear/canvas/events/MouseEvent.hxx>
#include "events/MouseEvent.hxx" #include <simgear/canvas/elements/CanvasElement.hxx>
#include <cmath> #include <cmath>
namespace simgear namespace simgear
@@ -117,8 +113,6 @@ namespace canvas
return handled; return handled;
} }
case Event::DRAG: case Event::DRAG:
case Event::DRAG_START:
case Event::DRAG_END:
if( !_last_mouse_down.valid() ) if( !_last_mouse_down.valid() )
return false; return false;
else else
+1 -2
View File
@@ -1,5 +1,4 @@
///@file // Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+1 -4
View File
@@ -1,5 +1,4 @@
///@file // Mapping between canvas gui Event types and their names
/// Mapping between canvas gui Event types and their names
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -26,8 +25,6 @@ ENUM_MAPPING(MOUSE_UP, "mouseup", MouseEvent)
ENUM_MAPPING(CLICK, "click", MouseEvent) ENUM_MAPPING(CLICK, "click", MouseEvent)
ENUM_MAPPING(DBL_CLICK, "dblclick", MouseEvent) ENUM_MAPPING(DBL_CLICK, "dblclick", MouseEvent)
ENUM_MAPPING(DRAG, "drag", MouseEvent) ENUM_MAPPING(DRAG, "drag", MouseEvent)
ENUM_MAPPING(DRAG_START, "dragstart", MouseEvent)
ENUM_MAPPING(DRAG_END, "dragend", MouseEvent)
ENUM_MAPPING(WHEEL, "wheel", MouseEvent) ENUM_MAPPING(WHEEL, "wheel", MouseEvent)
ENUM_MAPPING(MOUSE_MOVE, "mousemove", MouseEvent) ENUM_MAPPING(MOUSE_MOVE, "mousemove", MouseEvent)
ENUM_MAPPING(MOUSE_OVER, "mouseover", MouseEvent) ENUM_MAPPING(MOUSE_OVER, "mouseover", MouseEvent)
+3 -6
View File
@@ -1,6 +1,5 @@
///@file // Visitor for traversing a canvas element hierarchy similar to the traversal
/// Visitor for traversing a canvas element hierarchy similar to the traversal // of the DOM Level 3 Event Model
/// of the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -18,11 +17,9 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasEvent.hxx" #include "CanvasEvent.hxx"
#include "CanvasEventVisitor.hxx" #include "CanvasEventVisitor.hxx"
#include "elements/CanvasElement.hxx" #include <simgear/canvas/elements/CanvasElement.hxx>
namespace simgear namespace simgear
{ {
+2 -3
View File
@@ -1,6 +1,5 @@
///@file // Visitor for traversing a canvas element hierarchy similar to the traversal
/// Visitor for traversing a canvas element hierarchy similar to the traversal // of the DOM Level 3 Event Model
/// of the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+3 -4
View File
@@ -1,5 +1,4 @@
///@file // Canvas with 2D rendering API
/// Canvas with 2D rendering API
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,12 +16,12 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasMgr.hxx" #include "CanvasMgr.hxx"
#include "Canvas.hxx" #include "Canvas.hxx"
#include "CanvasEventManager.hxx" #include "CanvasEventManager.hxx"
#include <boost/bind.hpp>
namespace simgear namespace simgear
{ {
namespace canvas namespace canvas
+6 -4
View File
@@ -1,5 +1,4 @@
///@file // Canvas with 2D rendering API
/// Canvas with 2D rendering API
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -28,9 +27,11 @@ namespace simgear
namespace canvas namespace canvas
{ {
class CanvasMgr : public PropertyBasedMgr class CanvasMgr:
public PropertyBasedMgr
{ {
public: public:
/** /**
* @param node Root node of branch used to control canvasses * @param node Root node of branch used to control canvasses
*/ */
@@ -59,7 +60,8 @@ public:
CanvasPtr getCanvas(const std::string& name) const; CanvasPtr getCanvas(const std::string& name) const;
protected: protected:
void elementCreated(PropertyBasedElementPtr element) override;
virtual void elementCreated(PropertyBasedElementPtr element);
}; };
} // namespace canvas } // namespace canvas
+1 -4
View File
@@ -1,5 +1,4 @@
///@file // Canvas placement for placing a canvas texture onto osg objects.
/// Canvas placement for placing a canvas texture onto osg objects
// //
// It also provides a SGPickCallback for passing mouse events to the canvas and // It also provides a SGPickCallback for passing mouse events to the canvas and
// manages emissive lighting of the placed canvas. // manages emissive lighting of the placed canvas.
@@ -20,8 +19,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "Canvas.hxx" #include "Canvas.hxx"
#include "CanvasObjectPlacement.hxx" #include "CanvasObjectPlacement.hxx"
#include <simgear/canvas/events/MouseEvent.hxx> #include <simgear/canvas/events/MouseEvent.hxx>
+2 -2
View File
@@ -1,5 +1,5 @@
///@file ///@file
/// Placement for putting a canvas texture onto OpenSceneGraph objects /// Placement for putting a canvas texture onto OpenSceneGraph objects.
/// ///
/// It also provides a SGPickCallback for passing mouse events to the canvas and /// It also provides a SGPickCallback for passing mouse events to the canvas and
/// manages emissive lighting of the placed canvas. /// manages emissive lighting of the placed canvas.
@@ -60,7 +60,7 @@ namespace canvas
*/ */
void setCaptureEvents(bool enable); void setCaptureEvents(bool enable);
bool childChanged(SGPropertyNode* child) override; virtual bool childChanged(SGPropertyNode* child);
protected: protected:
typedef SGSharedPtr<SGPickCallback> PickCallbackPtr; typedef SGSharedPtr<SGPickCallback> PickCallbackPtr;
+1 -3
View File
@@ -1,5 +1,4 @@
///@file // Base class for canvas placements
/// Base class for canvas placements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,7 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasPlacement.hxx" #include "CanvasPlacement.hxx"
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
+4 -4
View File
@@ -1,5 +1,4 @@
///@file // Base class for canvas placements
/// Base class for canvas placements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -41,8 +40,9 @@ namespace canvas
protected: protected:
SGPropertyNode_ptr _node; SGPropertyNode_ptr _node;
Placement(const Placement&) = delete; private:
Placement& operator=(const Placement&) = delete; Placement(const Placement&) /* = delete */;
Placement& operator=(const Placement&) /* = delete */;
}; };
} // namespace canvas } // namespace canvas
+1 -6
View File
@@ -1,5 +1,4 @@
///@file // Adapter for using the canvas with different applications
/// Adapter for using the canvas with different applications
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -30,10 +29,6 @@ namespace HTTP { class Client; }
namespace canvas namespace canvas
{ {
/**
* Provides access to different required systems of the application to the
* Canvas
*/
class SystemAdapter class SystemAdapter
{ {
public: public:
+15 -19
View File
@@ -1,5 +1,4 @@
///@file // Window for placing a Canvas onto it (for dialogs, menus, etc.)
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,17 +16,18 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasMgr.hxx" #include "CanvasMgr.hxx"
#include "CanvasSystemAdapter.hxx" #include "CanvasSystemAdapter.hxx"
#include "CanvasWindow.hxx" #include "CanvasWindow.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/scene/util/OsgMath.hxx> #include <simgear/scene/util/OsgMath.hxx>
#include <osgGA/GUIEventHandler> #include <osgGA/GUIEventHandler>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
namespace simgear namespace simgear
{ {
namespace canvas namespace canvas
@@ -42,6 +42,9 @@ namespace canvas
const Style& parent_style, const Style& parent_style,
Element* parent ): Element* parent ):
Image(canvas, node, parent_style, parent), Image(canvas, node, parent_style, parent),
_attributes_dirty(0),
_resizable(false),
_capture_events(true),
_resize_top(node, "resize-top"), _resize_top(node, "resize-top"),
_resize_right(node, "resize-right"), _resize_right(node, "resize-right"),
_resize_bottom(node, "resize-bottom"), _resize_bottom(node, "resize-bottom"),
@@ -88,7 +91,7 @@ namespace canvas
_capture_events = node->getBoolValue(); _capture_events = node->getBoolValue();
else if( name == "decoration-border" ) else if( name == "decoration-border" )
parseDecorationBorder(node->getStringValue()); parseDecorationBorder(node->getStringValue());
else if( strutils::starts_with(name, "shadow-") else if( boost::starts_with(name, "shadow-")
|| name == "content-size" ) || name == "content-size" )
_attributes_dirty |= DECORATION; _attributes_dirty |= DECORATION;
else else
@@ -99,10 +102,16 @@ namespace canvas
Image::valueChanged(node); Image::valueChanged(node);
} }
//----------------------------------------------------------------------------
osg::Group* Window::getGroup()
{
return getMatrixTransform();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const SGVec2<float> Window::getPosition() const const SGVec2<float> Window::getPosition() const
{ {
auto const& m = getMatrix(); const osg::Matrix& m = getMatrixTransform()->getMatrix();
return SGVec2<float>( m(3, 0), m(3, 1) ); return SGVec2<float>( m(3, 0), m(3, 1) );
} }
@@ -213,19 +222,6 @@ namespace canvas
_resize_left = getRegion().l() + offset.x(); _resize_left = getRegion().l() + offset.x();
} }
//----------------------------------------------------------------------------
bool Window::handleEvent(const EventPtr& event)
{
if( auto mouse_event = dynamic_cast<MouseEvent*>(event.get()) )
{
mouse_event->local_pos =
mouse_event->client_pos =
mouse_event->screen_pos - toOsg(getPosition());
}
return Image::handleEvent(event);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Window::parseDecorationBorder(const std::string& str) void Window::parseDecorationBorder(const std::string& str)
{ {
+9 -11
View File
@@ -1,5 +1,4 @@
///@file // Window for placing a Canvas onto it (for dialogs, menus, etc.)
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -68,9 +67,10 @@ namespace canvas
Element* parent = 0 ); Element* parent = 0 );
virtual ~Window(); virtual ~Window();
void update(double delta_time_sec) override; virtual void update(double delta_time_sec);
void valueChanged(SGPropertyNode* node) override; virtual void valueChanged(SGPropertyNode* node);
osg::Group* getGroup();
const SGVec2<float> getPosition() const; const SGVec2<float> getPosition() const;
const SGRect<float> getScreenRegion() const; const SGRect<float> getScreenRegion() const;
@@ -84,8 +84,8 @@ namespace canvas
bool isResizable() const; bool isResizable() const;
bool isCapturingEvents() const; bool isCapturingEvents() const;
void setVisible(bool visible) override; virtual void setVisible(bool visible);
bool isVisible() const override; virtual bool isVisible() const;
/** /**
* Moves window on top of all other windows with the same z-index. * Moves window on top of all other windows with the same z-index.
@@ -97,8 +97,6 @@ namespace canvas
void handleResize( uint8_t mode, void handleResize( uint8_t mode,
const osg::Vec2f& offset = osg::Vec2f() ); const osg::Vec2f& offset = osg::Vec2f() );
bool handleEvent(const EventPtr& event) override;
protected: protected:
enum Attributes enum Attributes
@@ -106,7 +104,7 @@ namespace canvas
DECORATION = 1 DECORATION = 1
}; };
uint32_t _attributes_dirty {0}; uint32_t _attributes_dirty;
CanvasPtr _canvas_decoration; CanvasPtr _canvas_decoration;
CanvasWeakPtr _canvas_content; CanvasWeakPtr _canvas_content;
@@ -115,8 +113,8 @@ namespace canvas
ImagePtr _image_content, ImagePtr _image_content,
_image_shadow; _image_shadow;
bool _resizable {false}, bool _resizable,
_capture_events {true}; _capture_events;
PropertyObject<int> _resize_top, PropertyObject<int> _resize_top,
_resize_right, _resize_right,
+6 -19
View File
@@ -1,5 +1,4 @@
///@file // Owner Drawn Gauge helper class
/// Owner Drawn Gauge helper class
// //
// Written by Harald JOHNSEN, started May 2005. // Written by Harald JOHNSEN, started May 2005.
// //
@@ -7,9 +6,9 @@
// //
// Ported to OSG by Tim Moore - Jun 2007 // Ported to OSG by Tim Moore - Jun 2007
// //
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April // Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and // Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// placing the texture in the scene by certain filter criteria. // the texture in the scene by certain filter criteria
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -202,12 +201,6 @@ namespace canvas
updateSampling(); updateSampling();
} }
//----------------------------------------------------------------------------
void ODGauge::setMaxAnisotropy(float anis)
{
texture->setMaxAnisotropy(anis);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void ODGauge::setRender(bool render) void ODGauge::setRender(bool render)
{ {
@@ -256,16 +249,10 @@ namespace canvas
if( !texture ) if( !texture )
{ {
// It shouldn't be necessary to allocate an image for the
// texture that is the target of dynamic rendering, but
// otherwise OSG won't construct all the mipmaps for the texture
// and dynamic mipmap generation doesn't work.
osg::Image* image = new osg::Image;
image->allocateImage(_size_x, _size_y, 1, GL_RGBA, GL_UNSIGNED_BYTE);
texture = new osg::Texture2D; texture = new osg::Texture2D;
texture->setResizeNonPowerOfTwoHint(false); texture->setResizeNonPowerOfTwoHint(false);
texture->setImage(image); texture->setTextureSize(_size_x, _size_y);
texture->setUnRefImageDataAfterApply(true); texture->setInternalFormat(GL_RGBA);
} }
updateSampling(); updateSampling();
+4 -7
View File
@@ -1,5 +1,4 @@
///@file // Owner Drawn Gauge helper class
/// Owner Drawn Gauge helper class
// //
// Written by Harald JOHNSEN, started May 2005. // Written by Harald JOHNSEN, started May 2005.
// //
@@ -7,9 +6,9 @@
// //
// Ported to OSG by Tim Moore - Jun 2007 // Ported to OSG by Tim Moore - Jun 2007
// //
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April // Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
// 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and // Supports now multisampling/mipmapping, usage of the stencil buffer and placing
// placing the texture in the scene by certain filter criteria. // the texture in the scene by certain filter criteria
// //
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@@ -109,8 +108,6 @@ namespace canvas
int coverage_samples = 0, int coverage_samples = 0,
int color_samples = 0 ); int color_samples = 0 );
void setMaxAnisotropy(float anis);
/** /**
* Enable/Disable updating the texture (If disabled the contents of the * Enable/Disable updating the texture (If disabled the contents of the
* texture remains with the outcome of the last rendering pass) * texture remains with the outcome of the last rendering pass)
-5
View File
@@ -31,11 +31,6 @@
// FreeBSD // FreeBSD
#define VG_API_FREEBSD #define VG_API_FREEBSD
#elif defined(__OpenBSD__)
// FreeBSD
#define VG_API_OPENBSD
#else #else
// Unsupported system // Unsupported system
+2 -7
View File
@@ -34,7 +34,7 @@
#include <math.h> #include <math.h>
#include <float.h> #include <float.h>
#if !defined(VG_API_MACOSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) #if !defined(VG_API_MACOSX) && !defined(__FreeBSD__)
# include <malloc.h> # include <malloc.h>
#endif #endif
@@ -44,11 +44,6 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(disable:4311) # pragma warning(disable:4311)
# pragma warning(disable:4312) # pragma warning(disable:4312)
# define ALIGN16 __declspec(align(16))
# define ALIGN16C
#elif defined(__GNUC__)
# define ALIGN16
# define ALIGN16C __attribute__((aligned(16)))
#endif #endif
/* Type definitions */ /* Type definitions */
@@ -161,7 +156,7 @@ SHfloat getMaxFloat();
/* OpenGL headers */ /* OpenGL headers */
#if defined(VG_API_LINUX) || defined(VG_API_FREEBSD) || defined(VG_API_OPENBSD) #if defined(VG_API_LINUX) || defined(VG_API_FREEBSD)
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glx.h> #include <GL/glx.h>
#elif defined(VG_API_MACOSX) #elif defined(VG_API_MACOSX)
+1 -1
View File
@@ -1193,7 +1193,7 @@ VG_API_CALL VGboolean vgInterpolatePath(VGPath dstPath, VGPath startPath,
SHfloat *procData1, *procData2; SHfloat *procData1, *procData2;
SHint procSegCount1=0, procSegCount2=0; SHint procSegCount1=0, procSegCount2=0;
SHint procDataCount1=0, procDataCount2=0; SHint procDataCount1=0, procDataCount2=0;
SHuint8 *newSegs, *newData=0; SHuint8 *newSegs, *newData;
void *userData[4]; void *userData[4];
SHint segment1, segment2; SHint segment1, segment2;
SHint segindex, s,d,i; SHint segindex, s,d,i;
-33
View File
@@ -35,33 +35,21 @@ void SHVector2_dtor(SHVector2 *v) {
} }
void SHVector3_ctor(SHVector3 *v) { void SHVector3_ctor(SHVector3 *v) {
#ifdef SHIVA_USE_SIMD
v->vec = _mm_setzero_ps();
#else
v->x=0.0f; v->y=0.0f; v->z=0.0f; v->x=0.0f; v->y=0.0f; v->z=0.0f;
#endif
} }
void SHVector3_dtor(SHVector3 *v) { void SHVector3_dtor(SHVector3 *v) {
} }
void SHVector4_ctor(SHVector4 *v) { void SHVector4_ctor(SHVector4 *v) {
#ifdef SHIVA_USE_SIMD
v->vec = _mm_setzero_ps();
#else
v->x=0.0f; v->y=0.0f; v->z=0.0f; v->w=0.0f; v->x=0.0f; v->y=0.0f; v->z=0.0f; v->w=0.0f;
#endif
} }
void SHVector4_dtor(SHVector4 *v) { void SHVector4_dtor(SHVector4 *v) {
} }
void SHRectangle_ctor(SHRectangle *r) { void SHRectangle_ctor(SHRectangle *r) {
#ifdef SHIVA_USE_SIMD
r->vec = _mm_setzero_ps();
#else
r->x=0.0f; r->y=0.0f; r->w=0.0f; r->h=0.0f; r->x=0.0f; r->y=0.0f; r->w=0.0f; r->h=0.0f;
#endif
} }
void SHRectangle_dtor(SHRectangle *r) { void SHRectangle_dtor(SHRectangle *r) {
@@ -147,24 +135,3 @@ int shLineLineXsection(SHVector2 *o1, SHVector2 *v1,
xsection->y = o1->y + t1*v1->y; xsection->y = o1->y + t1*v1->y;
return 1; return 1;
} }
#ifdef SHIVA_USE_SIMD
# ifdef __SSE3__
# include <pmmintrin.h>
inline float hsum_ps_sse(__m128 v) {
__m128 shuf = _mm_movehdup_ps(v);
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums);
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
# else
inline float hsum_ps_sse(__m128 v) {
__m128 shuf = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 3, 0, 1));
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums);
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
# endif
#endif
+6 -149
View File
@@ -21,21 +21,6 @@
#ifndef __SHVECTORS_H #ifndef __SHVECTORS_H
#define __SHVECTORS_H #define __SHVECTORS_H
#ifdef HAVE_CONFIG_H
# include <simgear/simgear_config.h>
#endif
#ifdef ENABLE_SIMD
# ifdef __SSE__
// # define SHIVA_USE_SIMD
# endif
# endif
#ifdef SHIVA_USE_SIMD
# include <xmmintrin.h>
float hsum_ps_sse(__m128 v);
#endif
#include "shDefs.h" #include "shDefs.h"
/* Vector structures /* Vector structures
@@ -48,17 +33,9 @@ typedef struct
void SHVector2_ctor(SHVector2 *v); void SHVector2_ctor(SHVector2 *v);
void SHVector2_dtor(SHVector2 *v); void SHVector2_dtor(SHVector2 *v);
typedef struct typedef struct
{ {
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,z,w; };
} ALIGN16C;
#else
SHfloat x,y,z; SHfloat x,y,z;
#endif
} SHVector3; } SHVector3;
void SHVector3_ctor(SHVector3 *v); void SHVector3_ctor(SHVector3 *v);
@@ -66,14 +43,7 @@ void SHVector3_dtor(SHVector3 *v);
typedef struct typedef struct
{ {
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,z,w; };
} ALIGN16C;
#else
SHfloat x,y,z,w; SHfloat x,y,z,w;
#endif
} SHVector4; } SHVector4;
void SHVector4_ctor(SHVector4 *v); void SHVector4_ctor(SHVector4 *v);
@@ -81,14 +51,7 @@ void SHVector4_dtor(SHVector4 *v);
typedef struct typedef struct
{ {
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 vec;
struct { SHfloat x,y,w,h; };
} ALIGN16C;
#else
SHfloat x,y,w,h; SHfloat x,y,w,h;
#endif
} SHRectangle; } SHRectangle;
void SHRectangle_ctor(SHRectangle *r); void SHRectangle_ctor(SHRectangle *r);
@@ -98,14 +61,7 @@ void shRectangleSet(SHRectangle *r, SHfloat x,
typedef struct typedef struct
{ {
#ifdef SHIVA_USE_SIMD
union ALIGN16 {
__m128 mtx[4];
SHfloat m[4][4];
} ALIGN16C;
#else
SHfloat m[3][3]; SHfloat m[3][3];
#endif
} SHMatrix3x3; } SHMatrix3x3;
void SHMatrix3x3_ctor(SHMatrix3x3 *m); void SHMatrix3x3_ctor(SHMatrix3x3 *m);
@@ -127,22 +83,12 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
*--------------------------------------------------------- */ *--------------------------------------------------------- */
#define SET2(v,xs,ys) { v.x=xs; v.y=ys; } #define SET2(v,xs,ys) { v.x=xs; v.y=ys; }
#ifdef SHIVA_USE_SIMD
# define SET3(v,xs,ys,zs,ws) { v.vec=_mm_set_ps(0,zs,ys,xs); }
# define SET4(v,xs,ys,zs,ws) { v.vec=_mm_set_ps(ws,zs,ys,xs); }
#else
#define SET3(v,xs,ys,zs) { v.x=xs; v.y=ys; v.z=zs; } #define SET3(v,xs,ys,zs) { v.x=xs; v.y=ys; v.z=zs; }
#define SET4(v,xs,ys,zs,ws) { v.x=xs; v.y=ys; v.z=zs; v.w=ws; } #define SET4(v,xs,ys,zs,ws) { v.x=xs; v.y=ys; v.z=zs; v.w=ws; }
#endif
#define SET2V(v1,v2) { v1.x=v2.x; v1.y=v2.y; } #define SET2V(v1,v2) { v1.x=v2.x; v1.y=v2.y; }
#ifdef SHIVA_USE_SIMD
# define SET3V(v1,v2) { v1.vec=v2.vec; }
# define SET4V(v1,v2) { v1.vec=v2.vec; }
#else
#define SET3V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; } #define SET3V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; }
#define SET4V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; v1.w=v2.w; } #define SET4V(v1,v2) { v1.x=v2.x; v1.y=v2.y; v1.z=v2.z; v1.w=v2.w; }
#endif
#define EQ2(v,xx,yy) ( v.x==xx && v.y==yy ) #define EQ2(v,xx,yy) ( v.x==xx && v.y==yy )
#define EQ3(v,xx,yy,zz) ( v.x==xx && v.y==yy && v.z==zz ) #define EQ3(v,xx,yy,zz) ( v.x==xx && v.y==yy && v.z==zz )
@@ -157,89 +103,48 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
#define EQ4V(v1,v2) ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z && v1.w==v2.w ) #define EQ4V(v1,v2) ( v1.x==v2.x && v1.y==v2.y && v1.z==v2.z && v1.w==v2.w )
#define ADD2(v,xx,yy) { v.x+=xx; v.y+=yy; } #define ADD2(v,xx,yy) { v.x+=xx; v.y+=yy; }
#ifdef SHIVA_USE_SIMD
# define ADD3(v,xx,yy,zz,ww) { v.vec=_mm_add_ps(v.vec,_mm_set_ps(0,zz,yy,xx)); }
# define ADD4(v,xx,yy,zz,ww) { v.vec=_mm_add_ps(v.vec,_mm_set_ps(ww,zz,yy,xx)); }
#else
#define ADD3(v,xx,yy,zz) { v.x+=xx; v.y+=yy; v.z+=zz; } #define ADD3(v,xx,yy,zz) { v.x+=xx; v.y+=yy; v.z+=zz; }
#define ADD4(v,xx,yy,zz,ww) { v.x+=xx; v.y+=yy; v.z+=zz; v.w+=ww; } #define ADD4(v,xx,yy,zz,ww) { v.x+=xx; v.y+=yy; v.z+=zz; v.w+=ww; }
#endif
#define ADD2V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; } #define ADD2V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; }
#ifdef SHIVA_USE_SIMD
# define ADD3V(v1,v2) { v1.vec=_mm_add_ps(v1.vec,v2.vec); }
# define ADD4V(v1,v2) { v1.vec=_mm_add_ps(v1.vec,v2.vec); }
#else
#define ADD3V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; } #define ADD3V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; }
#define ADD4V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; v1.w+=v2.w; } #define ADD4V(v1,v2) { v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z; v1.w+=v2.w; }
#endif
#define SUB2(v,xx,yy) { v.x-=xx; v.y-=yy; } #define SUB2(v,xx,yy) { v.x-=xx; v.y-=yy; }
#ifdef SHIVA_USE_SIMD
# define SUB3(v,xx,yy,zz,ww) { v.vec=_mm_sub_ps(v.vec,_mm_set_ps(0,zz,yy,xx)); }
# define SUB4(v,xx,yy,zz,ww) { v.vec=_mm_sub_ps(v.vec,_mm_set_ps(ww,zz,yy,xx)); }
#else
#define SUB3(v,xx,yy,zz) { v.x-=xx; v.y-=yy; v.z-=zz; } #define SUB3(v,xx,yy,zz) { v.x-=xx; v.y-=yy; v.z-=zz; }
#define SUB4(v,xx,yy,zz,ww) { v.x-=xx; v.y-=yy; v.z-=zz; v.w-=v2.w; } #define SUB4(v,xx,yy,zz,ww) { v.x-=xx; v.y-=yy; v.z-=zz; v.w-=v2.w; }
#endif
#define SUB2V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; } #define SUB2V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; }
#ifdef SHIVA_USE_SIMD
# define SUB3V(v1,v2) { v1.vec=_mm_sub_ps(v1.vec,v2.vec); }
# define SUB4V(v1,v2) { v1.vec=_mm_sub_ps(v1.vec,v2.vec); }
#else
#define SUB3V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; } #define SUB3V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; }
#define SUB4V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; v1.w-=v2.w; } #define SUB4V(v1,v2) { v1.x-=v2.x; v1.y-=v2.y; v1.z-=v2.z; v1.w-=v2.w; }
#endif
#define MUL2(v,f) { v.x*=f; v.y*=f; } #define MUL2(v,f) { v.x*=f; v.y*=f; }
#ifdef SHIVA_USE_SIMD
# define MUL3(v,f) { v.vec=_mm_mul_ps(v.vec,_mm_set1_ps(f)); }
# define MUL4(v,f) { v.vec=_mm_mul_ps(v.vec,_mm_set1_ps(f)); }
#else
#define MUL3(v,f) { v.x*=f; v.y*=f; v.z*=z; } #define MUL3(v,f) { v.x*=f; v.y*=f; v.z*=z; }
#define MUL4(v,f) { v.x*=f; v.y*=f; v.z*=z; v.w*=w; } #define MUL4(v,f) { v.x*=f; v.y*=f; v.z*=z; v.w*=w; }
#endif
#define DIV2(v,f) { v.x/=f; v.y/=f; } #define DIV2(v,f) { v.x/=f; v.y/=f; }
#ifdef SHIVA_USE_SIMD
# define DIV3(v,f) { v.vec=_mm_div_ps(v.vec,_mm_set1_ps(f)); }
# define DIV4(v,f) { v.vec=_mm_div_ps(v.vec,_mm_set1_ps(f)); }
#else
#define DIV3(v,f) { v.x/=f; v.y/=f; v.z/=z; } #define DIV3(v,f) { v.x/=f; v.y/=f; v.z/=z; }
#define DIV4(v,f) { v.x/=f; v.y/=f; v.z/=z; v.w/=w; } #define DIV4(v,f) { v.x/=f; v.y/=f; v.z/=z; v.w/=w; }
#endif
#define ABS2(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); } #define ABS2(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); }
#ifdef SHIVA_USE_SIMD
# define ABS_MASK _mm_set1_ps(-0.f)
# define ABS3(v) { v.vec=_mm_andnot_ps(ABS_MASK, v.vec); }
# define ABS4(v) { v.vec=_mm_andnot_ps(ABS_MASK, v.vec); }
#else
#define ABS3(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); } #define ABS3(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); }
#define ABS4(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); v.w=SH_ABS(v.w); } #define ABS4(v) { v.x=SH_ABS(v.x); v.y=SH_ABS(v.y); v.z=SH_ABS(v.z); v.w=SH_ABS(v.w); }
#endif
#define NORMSQ2(v) DOT2(v,v) #define NORMSQ2(v) (v.x*v.x + v.y*v.y)
#define NORMSQ3(v) DOT3(v,v) #define NORMSQ3(v) (v.x*v.x + v.y*v.y + v.z*v.z)
#define NORMSQ4(v) DOT4(v,v) #define NORMSQ4(v) (v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w)
#define NORM2(v) SH_SQRT(NORMSQ2(v)) #define NORM2(v) SH_SQRT(NORMSQ2(v))
#define NORM3(v) SH_SQRT(NORMSQ3(v)) #define NORM3(v) SH_SQRT(NORMSQ3(v))
#define NORM4(v) SH_SQRT(NORMSQ4(v)) #define NORM4(v) SH_SQRT(NORMSQ4(v))
#define NORMALIZE2(v) { SHfloat n=NORM2(v); DIV2(v,n); } #define NORMALIZE2(v) { SHfloat n=NORM2(v); v.x/=n; v.y/=n; }
#define NORMALIZE3(v) { SHfloat n=NORM3(v); DIV3(v,n); } #define NORMALIZE3(v) { SHfloat n=NORM3(v); v.x/=n; v.y/=n; v.z/=n; }
#define NORMALIZE4(v) { SHfloat n=NORM4(v); DIV4(v,n); } #define NORMALIZE4(v) { SHfloat n=NORM4(v); v.x/=n; v.y/=n; v.z/=n; v.w/=w; }
#define DOT2(v1,v2) (v1.x*v2.x + v1.y*v2.y) #define DOT2(v1,v2) (v1.x*v2.x + v1.y*v2.y)
#ifdef SHIVA_USE_SIMD
# define DOT4(v1,v2) hsum_ps_sse(_mm_mul_ps(v1.vec,v2.vec))
# define DOT4(v1,v2) hsum_ps_sse(_mm_mul_ps(v1.vec,v2.vec))
#else
#define DOT3(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z) #define DOT3(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)
#define DOT4(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w) #define DOT4(v1,v2) (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w)
#endif
#define CROSS2(v1,v2) (v1.x*v2.y - v2.x*v1.y) #define CROSS2(v1,v2) (v1.x*v2.y - v2.x*v1.y)
@@ -247,83 +152,36 @@ void SHMatrix3x3_dtor(SHMatrix3x3 *m);
#define ANGLE2N(v1,v2) (SH_ACOS( DOT2(v1,v2) )) #define ANGLE2N(v1,v2) (SH_ACOS( DOT2(v1,v2) ))
#define OFFSET2V(v, o, s) { v.x += o.x*s; v.y += o.y*s; } #define OFFSET2V(v, o, s) { v.x += o.x*s; v.y += o.y*s; }
#ifdef SHIVA_USE_SIMD
# define OFFSET4V(v, o, s) { v.vec=_mm_add_ps(v.vec,_mm_mul_ps(o.vec,_mm_set1_ps(s))); }
# define OFFSET4V(v, o, s) { v.vec=_mm_add_ps(v.vec,_mm_mul_ps(o.vec,_mm_set1_ps(s))); }
#else
#define OFFSET3V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; } #define OFFSET3V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; }
#define OFFSET4V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; v.w += o.w*s; } #define OFFSET4V(v, o, s) { v.x += o.x*s; v.y += o.y*s; v.z += o.z*s; v.w += o.w*s; }
#endif
/*----------------------------------------------------- /*-----------------------------------------------------
* Macros for matrix operations * Macros for matrix operations
*-----------------------------------------------------*/ *-----------------------------------------------------*/
#ifdef SHIVA_USE_SIMD
# define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
mat.mtx[0] = _mm_set_ps(0,m02,m01,m00); \
mat.mtx[1] = _mm_set_ps(0,m12,m11,m10); \
mat.mtx[2] = _mm_set_ps(0,m22,m21,m20); \
mat.mtx[3] = _mm_setzero_ps(); }
#else
#define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \ #define SETMAT(mat, m00, m01, m02, m10, m11, m12, m20, m21, m22) { \
mat.m[0][0] = m00; mat.m[0][1] = m01; mat.m[0][2] = m02; \ mat.m[0][0] = m00; mat.m[0][1] = m01; mat.m[0][2] = m02; \
mat.m[1][0] = m10; mat.m[1][1] = m11; mat.m[1][2] = m12; \ mat.m[1][0] = m10; mat.m[1][1] = m11; mat.m[1][2] = m12; \
mat.m[2][0] = m20; mat.m[2][1] = m21; mat.m[2][2] = m22; } mat.m[2][0] = m20; mat.m[2][1] = m21; mat.m[2][2] = m22; }
#endif
#ifdef SHIVA_USE_SIMD
# define SETMATMAT(m1, m2) { \
m1.mtx[0] = m2.mtx[0]; \
m1.mtx[1] = m2.mtx[1]; \
m1.mtx[2] = m2.mtx[2]; }
#else
#define SETMATMAT(m1, m2) { \ #define SETMATMAT(m1, m2) { \
int i,j; \ int i,j; \
for(i=0;i<3;i++) \ for(i=0;i<3;i++) \
for(j=0;j<3;j++) \ for(j=0;j<3;j++) \
m1.m[i][j] = m2.m[i][j]; } m1.m[i][j] = m2.m[i][j]; }
#endif
#ifdef SHIVA_USE_SIMD
# define MULMATS(mat, s) { \
mat.mtx[0] = _mm_mul_ps(mat.mtx[0],_mm_set1_ps(s)); \
mat.mtx[1] = _mm_mul_ps(mat.mtx[1],_mm_set1_ps(s)); \
mat.mtx[2] = _mm_mul_ps(mat.mtx[2],_mm_set1_ps(s)); }
#else
#define MULMATS(mat, s) { \ #define MULMATS(mat, s) { \
int i,j; \ int i,j; \
for(i=0;i<3;i++) \ for(i=0;i<3;i++) \
for(j=0;j<3;j++) \ for(j=0;j<3;j++) \
mat.m[i][j] *= s; } mat.m[i][j] *= s; }
#endif
#ifdef SHIVA_USE_SIMD
# define DIVMATS(mat, s) { \
mat.mtx[0] = _mm_mul_ps(mat.mtx[0],_mm_set1_ps(1/s)); \
mat.mtx[1] = _mm_mul_ps(mat.mtx[1],_mm_set1_ps(1/s)); \
mat.mtx[2] = _mm_mul_ps(mat.mtx[2],_mm_set1_ps(1/s)); }
#else
#define DIVMATS(mat, s) { \ #define DIVMATS(mat, s) { \
int i,j; \ int i,j; \
for(i=0;i<3;i++) \ for(i=0;i<3;i++) \
for(j=0;j<3;j++) \ for(j=0;j<3;j++) \
mat.m[i][j] /= s; } mat.m[i][j] /= s; }
#endif
#ifdef SHIVA_USE_SIMD
# define MULMATMAT(m2, m1, mout) { \
int i,j; \
for (i=0;i<4;i++) { \
__m128 a = m1.mtx[0]; \
__m128 b = _mm_set1_ps(m2.m[i][0]); \
mout.mtx[i] = a*b; \
for (j=1;j<4;j++) { \
a = m1.mtx[j]; \
b = _mm_set1_ps(m2.m[i][j]); \
mout.mtx[i] += a*b; } } }
#else
#define MULMATMAT(m1, m2, mout) { \ #define MULMATMAT(m1, m2, mout) { \
int i,j; \ int i,j; \
for(i=0;i<3;i++) \ for(i=0;i<3;i++) \
@@ -332,7 +190,6 @@ int i,j; \
m1.m[i][0] * m2.m[0][j] + \ m1.m[i][0] * m2.m[0][j] + \
m1.m[i][1] * m2.m[1][j] + \ m1.m[i][1] * m2.m[1][j] + \
m1.m[i][2] * m2.m[2][j]; } m1.m[i][2] * m2.m[2][j]; }
#endif
#define IDMAT(mat) SETMAT(mat, 1,0,0, 0,1,0, 0,0,1) #define IDMAT(mat) SETMAT(mat, 1,0,0, 0,1,0, 0,0,1)
+1 -2
View File
@@ -1,5 +1,4 @@
///@file // osg::Operation to initialize the OpenVG context used for path rendering
/// osg::Operation to initialize the OpenVG context used for path rendering
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+1 -2
View File
@@ -1,5 +1,4 @@
///@file // osg::Operation to initialize the OpenVG context used for path rendering
/// osg::Operation to initialize the OpenVG context used for path rendering
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+9 -8
View File
@@ -1,5 +1,4 @@
///@file // Canvas forward declarations
/// Canvas forward declarations
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -26,9 +25,11 @@
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osgText/Font> #include <osgText/Font>
#include <functional> #include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <map> #include <map>
#include <memory>
#include <vector> #include <vector>
namespace simgear namespace simgear
@@ -60,8 +61,8 @@ namespace canvas
#define SG_FWD_DECL(name)\ #define SG_FWD_DECL(name)\
class name;\ class name;\
typedef std::shared_ptr<name> name##Ptr;\ typedef boost::shared_ptr<name> name##Ptr;\
typedef std::weak_ptr<name> name##WeakPtr; typedef boost::weak_ptr<name> name##WeakPtr;
SG_FWD_DECL(Placement) SG_FWD_DECL(Placement)
SG_FWD_DECL(SystemAdapter) SG_FWD_DECL(SystemAdapter)
@@ -83,10 +84,10 @@ namespace canvas
typedef osg::ref_ptr<osgText::Font> FontPtr; typedef osg::ref_ptr<osgText::Font> FontPtr;
typedef std::vector<PlacementPtr> Placements; typedef std::vector<PlacementPtr> Placements;
typedef std::function<Placements( SGPropertyNode*, typedef boost::function<Placements( SGPropertyNode*,
CanvasPtr )> PlacementFactory; CanvasPtr )> PlacementFactory;
typedef std::function<void(const EventPtr&)> EventListener; typedef boost::function<void(const EventPtr&)> EventListener;
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+5
View File
@@ -9,6 +9,10 @@ set(HEADERS
CanvasText.hxx CanvasText.hxx
) )
set(DETAIL_HEADERS
detail/add_segment_variadic.hxx
)
set(SOURCES set(SOURCES
CanvasElement.cxx CanvasElement.cxx
CanvasGroup.cxx CanvasGroup.cxx
@@ -19,6 +23,7 @@ set(SOURCES
) )
simgear_scene_component(canvas-elements canvas/elements "${SOURCES}" "${HEADERS}") simgear_scene_component(canvas-elements canvas/elements "${SOURCES}" "${HEADERS}")
simgear_component(canvas-elements/detail canvas/elements/detail "" "${DETAIL_HEADERS}")
add_boost_test(canvas_element add_boost_test(canvas_element
SOURCES canvas_element_test.cpp SOURCES canvas_element_test.cpp
+140 -178
View File
@@ -1,5 +1,4 @@
///@file // Interface for 2D Canvas element
/// Interface for 2D Canvas element
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasElement.hxx" #include "CanvasElement.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasEventVisitor.hxx> #include <simgear/canvas/CanvasEventVisitor.hxx>
@@ -32,6 +29,10 @@
#include <osg/StateAttribute> #include <osg/StateAttribute>
#include <osg/Version> #include <osg/Version>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
@@ -211,22 +212,22 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::onDestroy() void Element::onDestroy()
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
return; return;
// The transform node keeps a reference on this element, so ensure it is // The transform node keeps a reference on this element, so ensure it is
// deleted. // deleted.
for(osg::Group* parent: _scene_group->getParents()) BOOST_FOREACH(osg::Group* parent, _transform->getParents())
{ {
parent->removeChild(_scene_group.get()); parent->removeChild(_transform.get());
} }
// Hide in case someone still holds a reference // Hide in case someone still holds a reference
setVisible(false); setVisible(false);
removeListener(); removeListener();
_parent = nullptr; _parent = 0;
_scene_group = nullptr; _transform = 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -244,8 +245,29 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::update(double dt) void Element::update(double dt)
{ {
if( isVisible() ) if( !isVisible() )
updateImpl(dt); return;
// Trigger matrix update
getMatrix();
// Update bounding box on manual update (manual updates pass zero dt)
if( dt == 0 && _drawable )
_drawable->getBound();
if( (_attributes_dirty & BLEND_FUNC) && _transform.valid() )
{
parseBlendFunc(
_transform->getOrCreateStateSet(),
_node->getChild("blend-source"),
_node->getChild("blend-destination"),
_node->getChild("blend-source-rgb"),
_node->getChild("blend-destination-rgb"),
_node->getChild("blend-source-alpha"),
_node->getChild("blend-destination-alpha")
);
_attributes_dirty &= ~BLEND_FUNC;
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -272,7 +294,8 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::setFocus() void Element::setFocus()
{ {
if( auto canvas = _canvas.lock() ) CanvasPtr canvas = _canvas.lock();
if( canvas )
canvas->setFocusElement(this); canvas->setFocusElement(this);
} }
@@ -316,8 +339,7 @@ namespace canvas
if( listeners == _listener.end() ) if( listeners == _listener.end() )
return false; return false;
for(auto const& listener: listeners->second) BOOST_FOREACH(EventListener const& listener, listeners->second)
{
try try
{ {
listener(event); listener(event);
@@ -330,7 +352,6 @@ namespace canvas
"canvas::Element: event handler error: '" << ex.what() << "'" "canvas::Element: event handler error: '" << ex.what() << "'"
); );
} }
}
return true; return true;
} }
@@ -372,9 +393,9 @@ namespace canvas
getBoundingBox() getBoundingBox()
#endif #endif
.contains(osg::Vec3f(local_pos, 0)); .contains(osg::Vec3f(local_pos, 0));
else if( _scene_group.valid() ) else if( _transform.valid() )
// ... for other elements, i.e. groups only a bounding sphere is available // ... for other elements, i.e. groups only a bounding sphere is available
return _scene_group->getBound().contains(osg::Vec3f(parent_pos, 0)); return _transform->getBound().contains(osg::Vec3f(parent_pos, 0));
else else
return false; return false;
} }
@@ -383,32 +404,34 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::setVisible(bool visible) void Element::setVisible(bool visible)
{ {
if( _scene_group.valid() ) if( _transform.valid() )
// TODO check if we need another nodemask // TODO check if we need another nodemask
_scene_group->setNodeMask(visible ? 0xffffffff : 0); _transform->setNodeMask(visible ? 0xffffffff : 0);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Element::isVisible() const bool Element::isVisible() const
{ {
return _scene_group.valid() && _scene_group->getNodeMask() != 0; return _transform.valid() && _transform->getNodeMask() != 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::MatrixTransform* Element::getSceneGroup() const osg::MatrixTransform* Element::getMatrixTransform()
{ {
return _scene_group.get(); return _transform.get();
}
//----------------------------------------------------------------------------
osg::MatrixTransform const* Element::getMatrixTransform() const
{
return _transform.get();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::Vec2f Element::posToLocal(const osg::Vec2f& pos) const osg::Vec2f Element::posToLocal(const osg::Vec2f& pos) const
{ {
if( !_scene_group ) getMatrix();
// TODO log warning? const osg::Matrix& m = _transform->getInverseMatrix();
return pos;
updateMatrix();
const osg::Matrix& m = _scene_group->getInverseMatrix();
return osg::Vec2f return osg::Vec2f
( (
m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0), m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0),
@@ -461,6 +484,9 @@ namespace canvas
{ {
if( child->getNameString() == NAME_TRANSFORM ) if( child->getNameString() == NAME_TRANSFORM )
{ {
if( !_transform.valid() )
return;
if( child->getIndex() >= static_cast<int>(_transform_types.size()) ) if( child->getIndex() >= static_cast<int>(_transform_types.size()) )
{ {
SG_LOG SG_LOG
@@ -497,7 +523,7 @@ namespace canvas
if( parent == _node ) if( parent == _node )
{ {
const std::string& name = child->getNameString(); const std::string& name = child->getNameString();
if( strutils::starts_with(name, "data-") ) if( boost::starts_with(name, "data-") )
return; return;
else if( StyleInfo const* style_info = getStyleInfo(name) ) else if( StyleInfo const* style_info = getStyleInfo(name) )
{ {
@@ -512,7 +538,7 @@ namespace canvas
} }
else if( name == "update" ) else if( name == "update" )
return update(0); return update(0);
else if( strutils::starts_with(name, "blend-") ) else if( boost::starts_with(name, "blend-") )
return (void)(_attributes_dirty |= BLEND_FUNC); return (void)(_attributes_dirty |= BLEND_FUNC);
} }
else if( parent else if( parent
@@ -536,10 +562,6 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::setClip(const std::string& clip) void Element::setClip(const std::string& clip)
{ {
if( !_scene_group )
// TODO warn?
return;
osg::StateSet* ss = getOrCreateStateSet(); osg::StateSet* ss = getOrCreateStateSet();
if( !ss ) if( !ss )
return; return;
@@ -553,8 +575,8 @@ namespace canvas
// TODO generalize CSS property parsing // TODO generalize CSS property parsing
const std::string RECT("rect("); const std::string RECT("rect(");
if( !strutils::ends_with(clip, ")") if( !boost::ends_with(clip, ")")
|| !strutils::starts_with(clip, RECT) ) || !boost::starts_with(clip, RECT) )
{ {
SG_LOG(SG_GENERAL, SG_WARN, "Canvas: invalid clip: " << clip); SG_LOG(SG_GENERAL, SG_WARN, "Canvas: invalid clip: " << clip);
return; return;
@@ -594,7 +616,7 @@ namespace canvas
} }
if( !_scissor ) if( !_scissor )
_scissor = new RelativeScissor(_scene_group.get()); _scissor = new RelativeScissor(_transform.get());
// <top>, <right>, <bottom>, <left> // <top>, <right>, <bottom>, <left>
_scissor->x() = values[3]; _scissor->x() = values[3];
@@ -618,27 +640,6 @@ namespace canvas
_scissor->_coord_reference = rf; _scissor->_coord_reference = rf;
} }
//----------------------------------------------------------------------------
void Element::setRotation(unsigned int index, double r)
{
_node->getChild(NAME_TRANSFORM, index, true)->setDoubleValue("rot", r);
}
//----------------------------------------------------------------------------
void Element::setTranslation(unsigned int index, double x, double y)
{
SGPropertyNode* tf = _node->getChild(NAME_TRANSFORM, index, true);
tf->getChild("t", 0, true)->setDoubleValue(x);
tf->getChild("t", 1, true)->setDoubleValue(y);
}
//----------------------------------------------------------------------------
void Element::setTransformEnabled(unsigned int index, bool enabled)
{
SGPropertyNode* tf = _node->getChild(NAME_TRANSFORM, index, true);
tf->setBoolValue("enabled", enabled);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::BoundingBox Element::getBoundingBox() const osg::BoundingBox Element::getBoundingBox() const
{ {
@@ -651,8 +652,8 @@ namespace canvas
osg::BoundingBox bb; osg::BoundingBox bb;
if( _scene_group.valid() ) if( _transform.valid() )
bb.expandBy( _scene_group->getBound() ); bb.expandBy(_transform->getBound());
return bb; return bb;
} }
@@ -686,11 +687,70 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::Matrix Element::getMatrix() const osg::Matrix Element::getMatrix() const
{ {
if( !_scene_group ) if( !_transform )
return osg::Matrix::identity(); return osg::Matrix::identity();
updateMatrix(); if( !(_attributes_dirty & TRANSFORM) )
return _scene_group->getMatrix(); return _transform->getMatrix();
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_transform->setMatrix(m);
_attributes_dirty &= ~TRANSFORM;
return m;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -704,8 +764,11 @@ namespace canvas
PropertyBasedElement(node), PropertyBasedElement(node),
_canvas( canvas ), _canvas( canvas ),
_parent( parent ), _parent( parent ),
_scene_group( new osg::MatrixTransform ), _attributes_dirty( 0 ),
_style( parent_style ) _transform( new osg::MatrixTransform ),
_style( parent_style ),
_scissor( 0 ),
_drawable( 0 )
{ {
staticInit(); staticInit();
@@ -717,15 +780,15 @@ namespace canvas
); );
// Ensure elements are drawn in order they appear in the element tree // Ensure elements are drawn in order they appear in the element tree
_scene_group _transform->getOrCreateStateSet()
->getOrCreateStateSet() ->setRenderBinDetails
->setRenderBinDetails( (
0, 0,
"PreOrderBin", "PreOrderBin",
osg::StateSet::OVERRIDE_RENDERBIN_DETAILS osg::StateSet::OVERRIDE_RENDERBIN_DETAILS
); );
_scene_group->setUserData( new OSGUserData(this) ); _transform->setUserData( new OSGUserData(this) );
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -813,21 +876,11 @@ namespace canvas
void Element::setDrawable( osg::Drawable* drawable ) void Element::setDrawable( osg::Drawable* drawable )
{ {
_drawable = drawable; _drawable = drawable;
assert( _drawable );
if( !_drawable ) osg::ref_ptr<osg::Geode> geode = new osg::Geode;
{
SG_LOG(SG_GL, SG_WARN, "canvas::Element::setDrawable: NULL drawable");
return;
}
if( !_scene_group )
{
SG_LOG(SG_GL, SG_WARN, "canvas::Element::setDrawable: NULL scenegroup");
return;
}
auto geode = new osg::Geode;
geode->addDrawable(_drawable); geode->addDrawable(_drawable);
_scene_group->addChild(geode); _transform->addChild(geode);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -835,109 +888,18 @@ namespace canvas
{ {
if( _drawable.valid() ) if( _drawable.valid() )
return _drawable->getOrCreateStateSet(); return _drawable->getOrCreateStateSet();
else if( _scene_group.valid() ) if( _transform.valid() )
return _scene_group->getOrCreateStateSet(); return _transform->getOrCreateStateSet();
else
return nullptr; return 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::setupStyle() void Element::setupStyle()
{ {
for(auto const& style: _style) BOOST_FOREACH( Style::value_type style, _style )
setStyle(style.second); setStyle(style.second);
} }
//----------------------------------------------------------------------------
void Element::updateMatrix() const
{
if( !(_attributes_dirty & TRANSFORM) || !_scene_group )
return;
osg::Matrix m;
for( size_t i = 0; i < _transform_types.size(); ++i )
{
// Skip unused indizes...
if( _transform_types[i] == TT_NONE )
continue;
SGPropertyNode* tf_node = _node->getChild("tf", i, true);
if (!tf_node->getBoolValue("enabled", true)) {
continue; // skip disabled transforms
}
// Build up the matrix representation of the current transform node
osg::Matrix tf;
switch( _transform_types[i] )
{
case TT_MATRIX:
tf = osg::Matrix( tf_node->getDoubleValue("m[0]", 1),
tf_node->getDoubleValue("m[1]", 0),
0,
tf_node->getDoubleValue("m[6]", 0),
tf_node->getDoubleValue("m[2]", 0),
tf_node->getDoubleValue("m[3]", 1),
0,
tf_node->getDoubleValue("m[7]", 0),
0,
0,
1,
0,
tf_node->getDoubleValue("m[4]", 0),
tf_node->getDoubleValue("m[5]", 0),
0,
tf_node->getDoubleValue("m[8]", 1) );
break;
case TT_TRANSLATE:
tf.makeTranslate( osg::Vec3f( tf_node->getDoubleValue("t[0]", 0),
tf_node->getDoubleValue("t[1]", 0),
0 ) );
break;
case TT_ROTATE:
tf.makeRotate( tf_node->getDoubleValue("rot", 0), 0, 0, 1 );
break;
case TT_SCALE:
{
float sx = tf_node->getDoubleValue("s[0]", 1);
// sy defaults to sx...
tf.makeScale( sx, tf_node->getDoubleValue("s[1]", sx), 1 );
break;
}
default:
break;
}
m.postMult( tf );
}
_scene_group->setMatrix(m);
_attributes_dirty &= ~TRANSFORM;
}
//----------------------------------------------------------------------------
void Element::updateImpl(double dt)
{
updateMatrix();
// Update bounding box on manual update (manual updates pass zero dt)
if( dt == 0 && _drawable )
_drawable->getBound();
if( (_attributes_dirty & BLEND_FUNC) )
{
parseBlendFunc(
_scene_group->getOrCreateStateSet(),
_node->getChild("blend-source"),
_node->getChild("blend-destination"),
_node->getChild("blend-source-rgb"),
_node->getChild("blend-destination-rgb"),
_node->getChild("blend-source-alpha"),
_node->getChild("blend-destination-alpha")
);
_attributes_dirty &= ~BLEND_FUNC;
}
}
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+57 -67
View File
@@ -24,11 +24,14 @@
#include <simgear/canvas/CanvasEvent.hxx> #include <simgear/canvas/CanvasEvent.hxx>
#include <simgear/props/PropertyBasedElement.hxx> #include <simgear/props/PropertyBasedElement.hxx>
#include <simgear/misc/stdint.hxx> // for uint32_t #include <simgear/misc/stdint.hxx> // for uint32_t
#include <simgear/std/type_traits.hxx>
#include <osg/BoundingBox> #include <osg/BoundingBox>
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits/is_base_of.hpp>
namespace osg namespace osg
{ {
class Drawable; class Drawable;
@@ -46,7 +49,6 @@ namespace canvas
public PropertyBasedElement public PropertyBasedElement
{ {
public: public:
using SceneGroupWeakPtr = osg::observer_ptr<osg::MatrixTransform>;
/** /**
* Store pointer to window as user data * Store pointer to window as user data
@@ -59,9 +61,9 @@ namespace canvas
OSGUserData(ElementPtr element); OSGUserData(ElementPtr element);
}; };
typedef std::function<bool(Element&, const SGPropertyNode*)> typedef boost::function<bool(Element&, const SGPropertyNode*)>
StyleSetterFunc; StyleSetterFunc;
typedef std::function<void(Element&, const SGPropertyNode*)> typedef boost::function<void(Element&, const SGPropertyNode*)>
StyleSetterFuncUnchecked; StyleSetterFuncUnchecked;
struct StyleSetter: struct StyleSetter:
public SGReferenced public SGReferenced
@@ -92,7 +94,7 @@ namespace canvas
* *
*/ */
virtual ~Element() = 0; virtual ~Element() = 0;
void onDestroy() override; virtual void onDestroy();
ElementPtr getParent() const; ElementPtr getParent() const;
CanvasWeakPtr getCanvas() const; CanvasWeakPtr getCanvas() const;
@@ -102,7 +104,7 @@ namespace canvas
* *
* @param dt Frame time in seconds * @param dt Frame time in seconds
*/ */
void update(double dt) override; virtual void update(double dt);
bool addEventListener(const std::string& type, const EventListener& cb); bool addEventListener(const std::string& type, const EventListener& cb);
virtual void clearEventListener(); virtual void clearEventListener();
@@ -140,20 +142,19 @@ namespace canvas
*/ */
virtual bool isVisible() const; virtual bool isVisible() const;
/** osg::MatrixTransform* getMatrixTransform();
* Get the according group in the OSG scene graph osg::MatrixTransform const* getMatrixTransform() const;
*/
// TODO ref_ptr
osg::MatrixTransform* getSceneGroup() const;
/** /**
* Transform position to local coordinages. * Transform position to local coordinages.
*/ */
osg::Vec2f posToLocal(const osg::Vec2f& pos) const; osg::Vec2f posToLocal(const osg::Vec2f& pos) const;
void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override; virtual void childAdded( SGPropertyNode * parent,
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override; SGPropertyNode * child );
void valueChanged(SGPropertyNode* child) override; virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged(SGPropertyNode * child);
virtual bool setStyle( const SGPropertyNode* child, virtual bool setStyle( const SGPropertyNode* child,
const StyleInfo* style_info = 0 ); const StyleInfo* style_info = 0 );
@@ -171,22 +172,6 @@ namespace canvas
*/ */
void setClipFrame(ReferenceFrame rf); void setClipFrame(ReferenceFrame rf);
/**
*
*/
void setRotation(unsigned int index, double r);
/**
*
*/
void setTranslation(unsigned int index, double x, double y);
/**
*
*
*/
void setTransformEnabled(unsigned int index, bool enabled);
/** /**
* Get bounding box (may not be as tight as bounding box returned by * Get bounding box (may not be as tight as bounding box returned by
* #getTightBoundingBox) * #getTightBoundingBox)
@@ -216,11 +201,10 @@ namespace canvas
*/ */
template<typename Derived> template<typename Derived>
static static
std::enable_if_t< typename boost::enable_if<
std::is_base_of<Element, Derived>::value, boost::is_base_of<Element, Derived>,
ElementPtr ElementPtr
> >::type create( const CanvasWeakPtr& canvas,
create( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& style = Style(), const Style& style = Style(),
Element* parent = NULL ) Element* parent = NULL )
@@ -251,13 +235,13 @@ namespace canvas
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
ElementWeakPtr _parent; ElementWeakPtr _parent;
mutable uint32_t _attributes_dirty = 0; mutable uint32_t _attributes_dirty;
SceneGroupWeakPtr _scene_group; osg::observer_ptr<osg::MatrixTransform> _transform;
std::vector<TransformType> _transform_types; std::vector<TransformType> _transform_types;
Style _style; Style _style;
RelativeScissor *_scissor = nullptr; RelativeScissor *_scissor;
typedef std::vector<EventListener> Listener; typedef std::vector<EventListener> Listener;
typedef std::map<int, Listener> ListenerMap; typedef std::map<int, Listener> ListenerMap;
@@ -316,7 +300,7 @@ namespace canvas
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
const std::function<void (Derived&, T2)>& setter, const boost::function<void (Derived&, T2)>& setter,
bool inheritable = true ) bool inheritable = true )
{ {
StyleInfo& style_info = _style_setters[ name ]; StyleInfo& style_info = _style_setters[ name ];
@@ -342,10 +326,13 @@ namespace canvas
if( style->func ) if( style->func )
style = style->next = new StyleSetter; style = style->next = new StyleSetter;
style->func = std::bind(&type_match<Derived>::call, style->func = boost::bind
std::placeholders::_1, (
std::placeholders::_2, &type_match<Derived>::call,
bindStyleSetter<T1>(name, setter)); _1,
_2,
bindStyleSetter<T1>(name, setter)
);
return *style; return *style;
} }
@@ -357,7 +344,7 @@ namespace canvas
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
const std::function<void (Derived&, T)>& setter, const boost::function<void (Derived&, T)>& setter,
bool inheritable = true ) bool inheritable = true )
{ {
return addStyle<T, T>(name, type, setter, inheritable); return addStyle<T, T>(name, type, setter, inheritable);
@@ -378,7 +365,7 @@ namespace canvas
( (
name, name,
type, type,
std::function<void (Derived&, T)>(setter), boost::function<void (Derived&, T)>(setter),
inheritable inheritable
); );
} }
@@ -399,7 +386,7 @@ namespace canvas
( (
name, name,
type, type,
std::function<void (Derived&, T2)>(setter), boost::function<void (Derived&, T2)>(setter),
inheritable inheritable
); );
} }
@@ -418,7 +405,7 @@ namespace canvas
( (
name, name,
type, type,
std::function<void (Derived&, const std::string&)>(setter), boost::function<void (Derived&, const std::string&)>(setter),
inheritable inheritable
); );
} }
@@ -481,7 +468,7 @@ namespace canvas
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
const std::function<void (Other&, T2)>& setter, const boost::function<void (Other&, T2)>& setter,
OtherRef Derived::*instance_ref, OtherRef Derived::*instance_ref,
bool inheritable = true ) bool inheritable = true )
{ {
@@ -511,7 +498,7 @@ namespace canvas
( (
name, name,
type, type,
std::function<void (Other&, const std::string&)>(setter), boost::function<void (Other&, const std::string&)>(setter),
instance_ref, instance_ref,
inheritable inheritable
); );
@@ -519,37 +506,44 @@ namespace canvas
template<typename T, class Derived, class Other, class OtherRef> template<typename T, class Derived, class Other, class OtherRef>
static static
std::function<void (Derived&, T)> boost::function<void (Derived&, T)>
bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref ) bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref )
{ {
return std::bind(setter, return boost::bind(setter, boost::bind(instance_ref, _1), _2);
std::bind(instance_ref, std::placeholders::_1),
std::placeholders::_2);
} }
template<typename T, class Derived, class Other, class OtherRef> template<typename T, class Derived, class Other, class OtherRef>
static static
std::function<void (Derived&, T)> boost::function<void (Derived&, T)>
bindOther( const std::function<void (Other&, T)>& setter, bindOther( const boost::function<void (Other&, T)>& setter,
OtherRef Derived::*instance_ref ) OtherRef Derived::*instance_ref )
{ {
return std::bind(setter, return boost::bind
std::bind(&reference_from_pointer<Other, OtherRef>, (
std::bind(instance_ref, std::placeholders::_1)), setter,
std::placeholders::_2); boost::bind
(
&reference_from_pointer<Other, OtherRef>,
boost::bind(instance_ref, _1)
),
_2
);
} }
template<typename T1, typename T2, class Derived> template<typename T1, typename T2, class Derived>
static static
StyleSetterFuncUnchecked StyleSetterFuncUnchecked
bindStyleSetter( const std::string& name, bindStyleSetter( const std::string& name,
const std::function<void (Derived&, T2)>& setter ) const boost::function<void (Derived&, T2)>& setter )
{ {
return std::bind(setter, return boost::bind
(
setter,
// We will only call setters with Derived instances, so we can safely // We will only call setters with Derived instances, so we can safely
// cast here. // cast here.
std::bind(&derived_cast<Derived>, std::placeholders::_1), boost::bind(&derived_cast<Derived>, _1),
std::bind(&getValue<T1>, std::placeholders::_2)); boost::bind(&getValue<T1>, _2)
);
} }
bool isStyleEmpty(const SGPropertyNode* child) const; bool isStyleEmpty(const SGPropertyNode* child) const;
@@ -574,15 +568,11 @@ namespace canvas
void setupStyle(); void setupStyle();
void updateMatrix() const;
virtual void updateImpl(double dt);
private: private:
osg::ref_ptr<osg::Drawable> _drawable; osg::ref_ptr<osg::Drawable> _drawable;
Element(const Element&) = delete; Element(const Element&);// = delete
template<class Derived> template<class Derived>
static Derived& derived_cast(Element& el) static Derived& derived_cast(Element& el)
+72 -75
View File
@@ -1,5 +1,4 @@
///@file // A group of 2D Canvas elements
/// A group of 2D Canvas elements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,17 +16,18 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasGroup.hxx" #include "CanvasGroup.hxx"
#include "CanvasImage.hxx" #include "CanvasImage.hxx"
#include "CanvasMap.hxx" #include "CanvasMap.hxx"
#include "CanvasPath.hxx" #include "CanvasPath.hxx"
#include "CanvasText.hxx" #include "CanvasText.hxx"
#include <simgear/canvas/CanvasEventVisitor.hxx> #include <simgear/canvas/CanvasEventVisitor.hxx>
#include <simgear/canvas/events/MouseEvent.hxx> #include <simgear/canvas/events/MouseEvent.hxx>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/lambda/core.hpp>
namespace simgear namespace simgear
{ {
namespace canvas namespace canvas
@@ -46,7 +46,7 @@ namespace canvas
ElementFactories Group::_child_factories; ElementFactories Group::_child_factories;
const std::string Group::TYPE_NAME = "group"; const std::string Group::TYPE_NAME = "group";
void warnSceneGroupExpired(const char* member_name) void warnTransformExpired(const char* member_name)
{ {
SG_LOG( SG_GENERAL, SG_LOG( SG_GENERAL,
SG_WARN, SG_WARN,
@@ -133,59 +133,64 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ElementPtr Group::getElementById(const std::string& id) ElementPtr Group::getElementById(const std::string& id)
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
{ {
warnSceneGroupExpired("getElementById"); warnTransformExpired("getElementById");
return {}; return ElementPtr();
} }
// TODO check search algorithm. Not completely breadth-first and might be std::vector<GroupPtr> groups;
// possible with using less dynamic memory for(size_t i = 0; i < _transform->getNumChildren(); ++i)
std::vector<GroupPtr> child_groups;
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
{ {
const ElementPtr& el = getChildByIndex(i); const ElementPtr& el = getChildByIndex(i);
if( el->get<std::string>("id") == id ) if( el->get<std::string>("id") == id )
return el; return el;
if( Group* child_group = dynamic_cast<Group*>(el.get()) ) Group* group = dynamic_cast<Group*>(el.get());
child_groups.push_back(child_group); if( group )
groups.push_back(group);
} }
for(auto group: child_groups) BOOST_FOREACH( GroupPtr group, groups )
{ {
if( ElementPtr el = group->getElementById(id) ) ElementPtr el = group->getElementById(id);
if( el )
return el; return el;
} }
return {}; return ElementPtr();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Group::clearEventListener() void Group::clearEventListener()
{ {
Element::clearEventListener(); if( !_transform.valid() )
return warnTransformExpired("clearEventListener");
if( !_scene_group.valid() ) for(size_t i = 0; i < _transform->getNumChildren(); ++i)
return warnSceneGroupExpired("clearEventListener");
// TODO should this be recursive?
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
getChildByIndex(i)->clearEventListener(); getChildByIndex(i)->clearEventListener();
Element::clearEventListener();
}
//----------------------------------------------------------------------------
void Group::update(double dt)
{
for(size_t i = 0; i < _transform->getNumChildren(); ++i)
getChildByIndex(i)->update(dt);
Element::update(dt);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Group::traverse(EventVisitor& visitor) bool Group::traverse(EventVisitor& visitor)
{
if( _scene_group.valid() )
{ {
// Iterate in reverse order as last child is displayed on top // Iterate in reverse order as last child is displayed on top
for(size_t i = _scene_group->getNumChildren(); i --> 0;) for(size_t i = _transform->getNumChildren(); i --> 0;)
{ {
if( getChildByIndex(i)->accept(visitor) ) if( getChildByIndex(i)->accept(visitor) )
return true; return true;
} }
}
return false; return false;
} }
@@ -199,13 +204,13 @@ namespace canvas
bool handled = setStyleImpl(style, style_info); bool handled = setStyleImpl(style, style_info);
if( style_info->inheritable ) if( style_info->inheritable )
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
{ {
warnSceneGroupExpired("setStyle"); warnTransformExpired("setStyle");
return false; return false;
} }
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i) for(size_t i = 0; i < _transform->getNumChildren(); ++i)
handled |= getChildByIndex(i)->setStyle(style, style_info); handled |= getChildByIndex(i)->setStyle(style, style_info);
} }
@@ -215,20 +220,26 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::BoundingBox Group::getTransformedBounds(const osg::Matrix& m) const osg::BoundingBox Group::getTransformedBounds(const osg::Matrix& m) const
{ {
if( !_scene_group.valid() ) osg::BoundingBox bb;
if( !_transform.valid() )
{ {
warnSceneGroupExpired("getTransformedBounds"); warnTransformExpired("getTransformedBounds");
return {}; return bb;
} }
osg::BoundingBox bb; for(size_t i = 0; i < _transform->getNumChildren(); ++i)
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
{ {
auto child = getChildByIndex(i); const ElementPtr& child = getChildByIndex(i);
if( !child || !child->isVisible() ) if( !child->getMatrixTransform()->getNodeMask() )
continue; continue;
bb.expandBy( child->getTransformedBounds(child->getMatrix() * m) ); bb.expandBy
(
child->getTransformedBounds
(
child->getMatrixTransform()->getMatrix() * m
)
);
} }
return bb; return bb;
@@ -244,15 +255,6 @@ namespace canvas
return ElementFactory(); return ElementFactory();
} }
//----------------------------------------------------------------------------
void Group::updateImpl(double dt)
{
Element::updateImpl(dt);
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
getChildByIndex(i)->update(dt);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Group::childAdded(SGPropertyNode* child) void Group::childAdded(SGPropertyNode* child)
{ {
@@ -262,13 +264,13 @@ namespace canvas
ElementFactory child_factory = getChildFactory( child->getNameString() ); ElementFactory child_factory = getChildFactory( child->getNameString() );
if( child_factory ) if( child_factory )
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
return warnSceneGroupExpired("childAdded"); return warnTransformExpired("childAdded");
ElementPtr element = child_factory(_canvas, child, _style, this); ElementPtr element = child_factory(_canvas, child, _style, this);
// Add to osg scene graph... // Add to osg scene graph...
_scene_group->addChild(element->getSceneGroup()); _transform->addChild( element->getMatrixTransform() );
// ...and ensure correct ordering // ...and ensure correct ordering
handleZIndexChanged(element); handleZIndexChanged(element);
@@ -289,7 +291,7 @@ namespace canvas
if( getChildFactory(node->getNameString()) ) if( getChildFactory(node->getNameString()) )
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
// If transform is destroyed also all children are destroyed, so we can // If transform is destroyed also all children are destroyed, so we can
// not do anything here. // not do anything here.
return; return;
@@ -319,7 +321,7 @@ namespace canvas
void Group::childChanged(SGPropertyNode* node) void Group::childChanged(SGPropertyNode* node)
{ {
SGPropertyNode* parent = node->getParent(); SGPropertyNode* parent = node->getParent();
SGPropertyNode* grand_parent = parent ? parent->getParent() : nullptr; SGPropertyNode* grand_parent = parent ? parent->getParent() : NULL;
if( grand_parent == _node if( grand_parent == _node
&& node->getNameString() == "z-index" ) && node->getNameString() == "z-index" )
@@ -329,18 +331,16 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Group::handleZIndexChanged(ElementPtr child, int z_index) void Group::handleZIndexChanged(ElementPtr child, int z_index)
{ {
if( !child || !_scene_group.valid() ) if( !child || !_transform.valid() )
return; return;
// Keep reference to prevent deleting while removing and re-inserting later osg::ref_ptr<osg::MatrixTransform> tf = child->getMatrixTransform();
osg::ref_ptr<osg::MatrixTransform> tf = child->getSceneGroup(); size_t index = _transform->getChildIndex(tf),
size_t index = _scene_group->getChildIndex(tf),
index_new = index; index_new = index;
for(;; ++index_new) for(;; ++index_new)
{ {
if( index_new + 1 == _scene_group->getNumChildren() ) if( index_new + 1 == _transform->getNumChildren() )
break; break;
// Move to end of block with same index (= move upwards until the next // Move to end of block with same index (= move upwards until the next
@@ -367,13 +367,13 @@ namespace canvas
return; return;
} }
_scene_group->removeChild(index); _transform->removeChild(index);
_scene_group->insertChild(index_new, tf); _transform->insertChild(index_new, tf);
SG_LOG SG_LOG
( (
SG_GENERAL, SG_GENERAL,
SG_DEBUG, SG_INFO,
"canvas::Group: Moved element " << index << " to position " << index_new "canvas::Group: Moved element " << index << " to position " << index_new
); );
} }
@@ -381,27 +381,24 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ElementPtr Group::getChildByIndex(size_t index) const ElementPtr Group::getChildByIndex(size_t index) const
{ {
assert( _scene_group.valid() ); assert(_transform.valid());
OSGUserData* ud =
auto child = _scene_group->getChild(index); static_cast<OSGUserData*>(_transform->getChild(index)->getUserData());
if( !child ) assert(ud);
return {}; return ud->element;
auto ud = static_cast<OSGUserData*>(child->getUserData());
return ud ? ud->element : ElementPtr();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ElementPtr Group::findChild( const SGPropertyNode* node, ElementPtr Group::findChild( const SGPropertyNode* node,
const std::string& id ) const const std::string& id ) const
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
{ {
warnSceneGroupExpired("findChild"); warnTransformExpired("findChild");
return {}; return ElementPtr();
} }
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i) for(size_t i = 0; i < _transform->getNumChildren(); ++i)
{ {
ElementPtr el = getChildByIndex(i); ElementPtr el = getChildByIndex(i);
@@ -417,7 +414,7 @@ namespace canvas
} }
} }
return {}; return ElementPtr();
} }
} // namespace canvas } // namespace canvas
+11 -13
View File
@@ -1,5 +1,4 @@
///@file // A group of 2D Canvas elements
/// A group of 2D Canvas elements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -87,15 +86,16 @@ namespace canvas
*/ */
ElementPtr getElementById(const std::string& id); ElementPtr getElementById(const std::string& id);
void clearEventListener() override; virtual void clearEventListener();
bool traverse(EventVisitor& visitor) override; virtual void update(double dt);
bool setStyle( const SGPropertyNode* child, virtual bool traverse(EventVisitor& visitor);
const StyleInfo* style_info = 0 ) override;
osg::BoundingBox virtual bool setStyle( const SGPropertyNode* child,
getTransformedBounds(const osg::Matrix& m) const override; const StyleInfo* style_info = 0 );
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
protected: protected:
@@ -107,11 +107,9 @@ namespace canvas
*/ */
virtual ElementFactory getChildFactory(const std::string& type) const; virtual ElementFactory getChildFactory(const std::string& type) const;
void updateImpl(double dt) override; virtual void childAdded(SGPropertyNode * child);
virtual void childRemoved(SGPropertyNode * child);
void childAdded(SGPropertyNode * child) override; virtual void childChanged(SGPropertyNode * child);
void childRemoved(SGPropertyNode * child) override;
void childChanged(SGPropertyNode * child) override;
void handleZIndexChanged(ElementPtr child, int z_index = 0); void handleZIndexChanged(ElementPtr child, int z_index = 0);
+179 -336
View File
@@ -1,5 +1,4 @@
///@file // An image on the Canvas
/// An image on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasImage.hxx" #include "CanvasImage.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
@@ -118,7 +115,9 @@ namespace canvas
ElementWeakPtr parent ): ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D), _texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ) _node_src_rect( node->getNode("source", 0, true) ),
_src_rect(0,0),
_region(0,0)
{ {
staticInit(); staticInit();
@@ -156,207 +155,22 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Image::~Image() Image::~Image()
{ {
if( _http_request ) if( _http_request ) {
{ Canvas::getSystemAdapter()->getHTTPClient()->cancelRequest(_http_request, "image destroyed");
Canvas::getSystemAdapter()
->getHTTPClient()
->cancelRequest(_http_request, "image destroyed");
} }
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Image::valueChanged(SGPropertyNode* child) void Image::update(double dt)
{ {
// If the image is switched from invisible to visible, and it shows a Element::update(dt);
// canvas, we need to delay showing it by one frame to ensure the canvas is
// updated before the image is displayed.
//
// As canvas::Element handles and filters changes to the "visible" property
// we can not check this in Image::childChanged but instead have to override
// Element::valueChanged.
if( !isVisible()
&& child->getParent() == _node
&& child->getNameString() == "visible"
&& child->getBoolValue() )
{
CullCallback* cb =
#if OSG_VERSION_LESS_THAN(3,3,2)
static_cast<CullCallback*>
#else
dynamic_cast<CullCallback*>
#endif
( _geom->getCullCallback() );
if( cb )
cb->cullNextFrame();
}
Element::valueChanged(child);
}
//----------------------------------------------------------------------------
void Image::setSrcCanvas(CanvasPtr canvas)
{
CanvasPtr src_canvas = _src_canvas.lock(),
self_canvas = _canvas.lock();
if( src_canvas )
src_canvas->removeParentCanvas(self_canvas);
if( self_canvas )
self_canvas->removeChildCanvas(src_canvas);
_src_canvas = src_canvas = canvas;
_attributes_dirty |= SRC_CANVAS;
_geom->setCullCallback(canvas ? new CullCallback(canvas) : 0);
if( src_canvas )
{
setupDefaultDimensions();
if( self_canvas )
{
self_canvas->addChildCanvas(src_canvas);
src_canvas->addParentCanvas(self_canvas);
}
}
}
//----------------------------------------------------------------------------
CanvasWeakPtr Image::getSrcCanvas() const
{
return _src_canvas;
}
//----------------------------------------------------------------------------
void Image::setImage(osg::ref_ptr<osg::Image> img)
{
// remove canvas...
setSrcCanvas( CanvasPtr() );
_texture->setResizeNonPowerOfTwoHint(false);
_texture->setImage(img);
_texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
_texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
_geom->getOrCreateStateSet()
->setTextureAttributeAndModes(0, _texture);
if( img )
setupDefaultDimensions();
}
//----------------------------------------------------------------------------
void Image::setFill(const std::string& fill)
{
osg::Vec4 color(1,1,1,1);
if( !fill.empty() // If no color is given default to white
&& !parseColor(fill, color) )
return;
setFill(color);
}
//----------------------------------------------------------------------------
void Image::setFill(const osg::Vec4& color)
{
_colors->front() = color;
_colors->dirty();
}
//----------------------------------------------------------------------------
void Image::setOutset(const std::string& outset)
{
_outset = CSSBorder::parse(outset);
_attributes_dirty |= DEST_SIZE;
}
//----------------------------------------------------------------------------
void Image::setPreserveAspectRatio(const std::string& scale)
{
_preserve_aspect_ratio = SVGpreserveAspectRatio::parse(scale);
_attributes_dirty |= SRC_RECT;
}
//----------------------------------------------------------------------------
void Image::setSourceRect(const SGRect<float>& sourceRect)
{
_attributes_dirty |= SRC_RECT;
_src_rect = sourceRect;
}
//----------------------------------------------------------------------------
void Image::setSlice(const std::string& slice)
{
_slice = CSSBorder::parse(slice);
_attributes_dirty |= SRC_RECT | DEST_SIZE;
}
//----------------------------------------------------------------------------
void Image::setSliceWidth(const std::string& width)
{
_slice_width = CSSBorder::parse(width);
_attributes_dirty |= DEST_SIZE;
}
//----------------------------------------------------------------------------
const SGRect<float>& Image::getRegion() const
{
return _region;
}
//----------------------------------------------------------------------------
bool Image::handleEvent(const EventPtr& event)
{
bool handled = Element::handleEvent(event);
CanvasPtr src_canvas = _src_canvas.lock();
if( !src_canvas )
return handled;
if( MouseEventPtr mouse_event = dynamic_cast<MouseEvent*>(event.get()) )
{
mouse_event.reset( new MouseEvent(*mouse_event) );
mouse_event->client_pos = mouse_event->local_pos
- toOsg(_region.getMin());
osg::Vec2f size(_region.width(), _region.height());
if( _outset.isValid() )
{
CSSBorder::Offsets outset =
_outset.getAbsOffsets(getTextureDimensions());
mouse_event->client_pos += osg::Vec2f(outset.l, outset.t);
size.x() += outset.l + outset.r;
size.y() += outset.t + outset.b;
}
// Scale event pos according to canvas view size vs. displayed/screen size
mouse_event->client_pos.x() *= src_canvas->getViewWidth() / size.x();
mouse_event->client_pos.y() *= src_canvas->getViewHeight()/ size.y();
mouse_event->local_pos = mouse_event->client_pos;
handled |= src_canvas->handleMouseEvent(mouse_event);
}
else if( KeyboardEventPtr keyboard_event =
dynamic_cast<KeyboardEvent*>(event.get()) )
{
handled |= src_canvas->handleKeyboardEvent(keyboard_event);
}
return handled;
}
//----------------------------------------------------------------------------
void Image::updateImpl(double dt)
{
Element::updateImpl(dt);
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*> osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>
( (
_geom->getOrCreateStateSet() _geom->getOrCreateStateSet()
->getTextureAttribute(0, osg::StateAttribute::TEXTURE) ->getTextureAttribute(0, osg::StateAttribute::TEXTURE)
); );
auto canvas = _src_canvas.lock(); simgear::canvas::CanvasPtr canvas = _src_canvas.lock();
if( (_attributes_dirty & SRC_CANVAS) if( (_attributes_dirty & SRC_CANVAS)
// check if texture has changed (eg. due to resizing) // check if texture has changed (eg. due to resizing)
@@ -586,6 +400,175 @@ namespace canvas
} }
} }
//----------------------------------------------------------------------------
void Image::valueChanged(SGPropertyNode* child)
{
// If the image is switched from invisible to visible, and it shows a
// canvas, we need to delay showing it by one frame to ensure the canvas is
// updated before the image is displayed.
//
// As canvas::Element handles and filters changes to the "visible" property
// we can not check this in Image::childChanged but instead have to override
// Element::valueChanged.
if( !isVisible()
&& child->getParent() == _node
&& child->getNameString() == "visible"
&& child->getBoolValue() )
{
CullCallback* cb =
#if OSG_VERSION_LESS_THAN(3,3,2)
static_cast<CullCallback*>
#else
dynamic_cast<CullCallback*>
#endif
( _geom->getCullCallback() );
if( cb )
cb->cullNextFrame();
}
Element::valueChanged(child);
}
//----------------------------------------------------------------------------
void Image::setSrcCanvas(CanvasPtr canvas)
{
CanvasPtr src_canvas = _src_canvas.lock(),
self_canvas = _canvas.lock();
if( src_canvas )
src_canvas->removeParentCanvas(self_canvas);
if( self_canvas )
self_canvas->removeChildCanvas(src_canvas);
_src_canvas = src_canvas = canvas;
_attributes_dirty |= SRC_CANVAS;
_geom->setCullCallback(canvas ? new CullCallback(canvas) : 0);
if( src_canvas )
{
setupDefaultDimensions();
if( self_canvas )
{
self_canvas->addChildCanvas(src_canvas);
src_canvas->addParentCanvas(self_canvas);
}
}
}
//----------------------------------------------------------------------------
CanvasWeakPtr Image::getSrcCanvas() const
{
return _src_canvas;
}
//----------------------------------------------------------------------------
void Image::setImage(osg::ref_ptr<osg::Image> img)
{
// remove canvas...
setSrcCanvas( CanvasPtr() );
_texture->setResizeNonPowerOfTwoHint(false);
_texture->setImage(img);
_texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
_texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
_geom->getOrCreateStateSet()
->setTextureAttributeAndModes(0, _texture);
if( img )
setupDefaultDimensions();
}
//----------------------------------------------------------------------------
void Image::setFill(const std::string& fill)
{
osg::Vec4 color(1,1,1,1);
if( !fill.empty() // If no color is given default to white
&& !parseColor(fill, color) )
return;
_colors->front() = color;
_colors->dirty();
}
//----------------------------------------------------------------------------
void Image::setOutset(const std::string& outset)
{
_outset = CSSBorder::parse(outset);
_attributes_dirty |= DEST_SIZE;
}
//----------------------------------------------------------------------------
void Image::setPreserveAspectRatio(const std::string& scale)
{
_preserve_aspect_ratio = SVGpreserveAspectRatio::parse(scale);
_attributes_dirty |= SRC_RECT;
}
//----------------------------------------------------------------------------
void Image::setSlice(const std::string& slice)
{
_slice = CSSBorder::parse(slice);
_attributes_dirty |= SRC_RECT | DEST_SIZE;
}
//----------------------------------------------------------------------------
void Image::setSliceWidth(const std::string& width)
{
_slice_width = CSSBorder::parse(width);
_attributes_dirty |= DEST_SIZE;
}
//----------------------------------------------------------------------------
const SGRect<float>& Image::getRegion() const
{
return _region;
}
//----------------------------------------------------------------------------
bool Image::handleEvent(const EventPtr& event)
{
bool handled = Element::handleEvent(event);
CanvasPtr src_canvas = _src_canvas.lock();
if( !src_canvas )
return handled;
if( MouseEventPtr mouse_event = dynamic_cast<MouseEvent*>(event.get()) )
{
mouse_event.reset( new MouseEvent(*mouse_event) );
mouse_event->client_pos = mouse_event->local_pos
- toOsg(_region.getMin());
osg::Vec2f size(_region.width(), _region.height());
if( _outset.isValid() )
{
CSSBorder::Offsets outset =
_outset.getAbsOffsets(getTextureDimensions());
mouse_event->client_pos += osg::Vec2f(outset.l, outset.t);
size.x() += outset.l + outset.r;
size.y() += outset.t + outset.b;
}
// Scale event pos according to canvas view size vs. displayed/screen size
mouse_event->client_pos.x() *= src_canvas->getViewWidth() / size.x();
mouse_event->client_pos.y() *= src_canvas->getViewHeight()/ size.y();
mouse_event->local_pos = mouse_event->client_pos;
handled |= src_canvas->handleMouseEvent(mouse_event);
}
else if( KeyboardEventPtr keyboard_event =
dynamic_cast<KeyboardEvent*>(event.get()) )
{
handled |= src_canvas->handleKeyboardEvent(keyboard_event);
}
return handled;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Image::childChanged(SGPropertyNode* child) void Image::childChanged(SGPropertyNode* child)
{ {
@@ -636,9 +619,7 @@ namespace canvas
// Abort pending request // Abort pending request
if( _http_request ) if( _http_request )
{ {
Canvas::getSystemAdapter() Canvas::getSystemAdapter()->getHTTPClient()->cancelRequest(_http_request, "setting new image");
->getHTTPClient()
->cancelRequest(_http_request, "setting new image");
_http_request.reset(); _http_request.reset();
} }
@@ -838,143 +819,5 @@ namespace canvas
return false; return false;
} }
void Image::fillRect(const SGRect<int>& rect, const std::string& c)
{
osg::Vec4 color(1,1,1,1);
if(!c.empty() && !parseColor(c, color))
return;
fillRect(rect, color);
}
void fillRow(GLubyte* row, GLuint pixel, GLuint width, GLuint pixelBytes)
{
GLubyte* dst = row;
for (GLuint x = 0; x < width; ++x) {
memcpy(dst, &pixel, pixelBytes);
dst += pixelBytes;
}
}
SGRect<int> intersectRect(const SGRect<int>& a, const SGRect<int>& b)
{
SGVec2<int> m1 = max(a.getMin(), b.getMin());
SGVec2<int> m2 = min(a.getMax(), b.getMax());
return SGRect<int>(m1, m2);
}
void Image::fillRect(const SGRect<int>& rect, const osg::Vec4& color)
{
osg::ref_ptr<osg::Image> image = _texture->getImage();
if (!image) {
allocateImage();
image = _texture->getImage();
}
if (image->getDataVariance() != osg::Object::DYNAMIC) {
image->setDataVariance(osg::Object::DYNAMIC);
}
const auto format = image->getInternalTextureFormat();
auto clippedRect = intersectRect(rect, SGRect<int>(0, 0, image->s(), image->t()));
if ((clippedRect.width() == 0) || (clippedRect.height() == 0)) {
return;
}
GLubyte* rowData = nullptr;
size_t rowByteSize = 0;
GLuint pixelWidth = clippedRect.width();
GLuint pixel = 0;
GLuint pixelBytes = 0;
switch (format) {
case GL_RGBA8:
case GL_RGBA:
rowByteSize = pixelWidth * 4;
rowData = static_cast<GLubyte*>(alloca(rowByteSize));
// assume litte-endian, so read out backwards, hence when we memcpy
// the data, it ends up in RGBA order
pixel = color.asABGR();
pixelBytes = 4;
fillRow(rowData, pixel, pixelWidth, pixelBytes);
break;
case GL_RGB8:
case GL_RGB:
rowByteSize = pixelWidth * 3;
rowData = static_cast<GLubyte*>(alloca(rowByteSize));
pixel = color.asABGR();
pixelBytes = 3;
fillRow(rowData, pixel, pixelWidth, pixelBytes);
break;
default:
SG_LOG(SG_IO, SG_WARN, "Image::fillRect: unsupported internal image format:" << format);
return;
}
for (int row=clippedRect.t(); row < clippedRect.b(); ++row) {
GLubyte* imageData = image->data(clippedRect.l(), row);
memcpy(imageData, rowData, rowByteSize);
}
image->dirty();
auto c = getCanvas().lock();
c->enableRendering(true); // force a repaint
}
void Image::setPixel(int x, int y, const std::string& c)
{
osg::Vec4 color(1,1,1,1);
if(!c.empty() && !parseColor(c, color))
return;
setPixel(x, y, color);
}
void Image::setPixel(int x, int y, const osg::Vec4& color)
{
osg::ref_ptr<osg::Image> image = _texture->getImage();
if (!image) {
allocateImage();
image = _texture->getImage();
}
if (image->getDataVariance() != osg::Object::DYNAMIC) {
image->setDataVariance(osg::Object::DYNAMIC);
}
image->setColor(color, x, y);
}
void Image::dirtyPixels()
{
osg::ref_ptr<osg::Image> image = _texture->getImage();
if (!image)
return;
image->dirty();
auto c = getCanvas().lock();
c->enableRendering(true); // force a repaint
}
void Image::allocateImage()
{
osg::Image* image = new osg::Image;
// default to RGBA
image->allocateImage(_node->getIntValue("size[0]"), _node->getIntValue("size[1]"), 1, GL_RGBA, GL_UNSIGNED_BYTE);
image->setInternalTextureFormat(GL_RGBA);
_texture->setImage(image);
}
osg::ref_ptr<osg::Image> Image::getImage() const
{
if (!_texture)
return {};
return _texture->getImage();
}
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+9 -40
View File
@@ -1,5 +1,4 @@
///@file // An image on the Canvas
/// An image on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -54,14 +53,14 @@ namespace canvas
ElementWeakPtr parent = 0 ); ElementWeakPtr parent = 0 );
virtual ~Image(); virtual ~Image();
void valueChanged(SGPropertyNode* child) override; virtual void update(double dt);
virtual void valueChanged(SGPropertyNode* child);
void setSrcCanvas(CanvasPtr canvas); void setSrcCanvas(CanvasPtr canvas);
CanvasWeakPtr getSrcCanvas() const; CanvasWeakPtr getSrcCanvas() const;
void setImage(osg::ref_ptr<osg::Image> img); void setImage(osg::ref_ptr<osg::Image> img);
void setFill(const std::string& fill); void setFill(const std::string& fill);
void setFill(const osg::Vec4& color);
/** /**
* @see http://www.w3.org/TR/css3-background/#border-image-outset * @see http://www.w3.org/TR/css3-background/#border-image-outset
@@ -94,36 +93,10 @@ namespace canvas
const SGRect<float>& getRegion() const; const SGRect<float>& getRegion() const;
bool handleEvent(const EventPtr& event) override; bool handleEvent(const EventPtr& event);
/**
*
*/
void setSourceRect(const SGRect<float>& sourceRect);
/**
* fill the specified rectangle of the image, with an RGB value
*/
void fillRect(const SGRect<int>& rect, const std::string& color);
/**
* fill the specified rectangle of the image, with an RGB value
*/
void fillRect(const SGRect<int>& rect, const osg::Vec4& color);
void setPixel(int x, int y, const std::string& color);
void setPixel(int x, int y, const osg::Vec4& color);
/**
* mark the image pixels as modified, so the canvas is re-painted
*/
void dirtyPixels();
osg::ref_ptr<osg::Image> getImage() const;
// void setRow(int row, int offset, )
protected: protected:
enum ImageAttributes enum ImageAttributes
{ {
SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle
@@ -131,9 +104,7 @@ namespace canvas
SRC_CANVAS = DEST_SIZE << 1 SRC_CANVAS = DEST_SIZE << 1
}; };
void updateImpl(double dt) override; virtual void childChanged(SGPropertyNode * child);
void childChanged(SGPropertyNode * child) override;
void setupDefaultDimensions(); void setupDefaultDimensions();
SGRect<int> getTextureDimensions() const; SGRect<int> getTextureDimensions() const;
@@ -147,8 +118,6 @@ namespace canvas
HTTP::Request& request, HTTP::Request& request,
const std::string& type ); const std::string& type );
void allocateImage();
osg::ref_ptr<osg::Texture2D> _texture; osg::ref_ptr<osg::Texture2D> _texture;
// TODO optionally forward events to canvas // TODO optionally forward events to canvas
CanvasWeakPtr _src_canvas; CanvasWeakPtr _src_canvas;
@@ -160,9 +129,9 @@ namespace canvas
osg::ref_ptr<osg::Vec2Array> _texCoords; osg::ref_ptr<osg::Vec2Array> _texCoords;
osg::ref_ptr<osg::Vec4Array> _colors; osg::ref_ptr<osg::Vec4Array> _colors;
SGPropertyNode *_node_src_rect = nullptr; SGPropertyNode *_node_src_rect;
SGRect<float> _src_rect {0, 0}, SGRect<float> _src_rect,
_region {0, 0}; _region;
SVGpreserveAspectRatio _preserve_aspect_ratio; SVGpreserveAspectRatio _preserve_aspect_ratio;
+26 -68
View File
@@ -1,6 +1,5 @@
///@file // A group of 2D Canvas elements which get automatically transformed according
/// A group of 2D Canvas elements which get automatically transformed according // to the map parameters.
/// to the map parameters.
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -18,16 +17,14 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasMap.hxx" #include "CanvasMap.hxx"
#include "map/geo_node_pair.hxx" #include "map/geo_node_pair.hxx"
#include "map/projection.hxx" #include "map/projection.hxx"
#include <simgear/misc/strutils.hxx>
#include <cmath> #include <cmath>
#include <boost/algorithm/string/predicate.hpp>
#define LOG_GEO_RET(msg) \ #define LOG_GEO_RET(msg) \
{\ {\
SG_LOG\ SG_LOG\
@@ -49,12 +46,6 @@ namespace canvas
const std::string GEO = "-geo"; const std::string GEO = "-geo";
const std::string HDG = "hdg"; const std::string HDG = "hdg";
const std::string Map::TYPE_NAME = "map"; const std::string Map::TYPE_NAME = "map";
const std::string WEB_MERCATOR = "webmercator";
const std::string REF_LAT = "ref-lat";
const std::string REF_LON = "ref-lon";
const std::string SCREEN_RANGE = "screen-range";
const std::string RANGE = "range";
const std::string PROJECTION = "projection";
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::staticInit() void Map::staticInit()
@@ -72,11 +63,12 @@ namespace canvas
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): ElementWeakPtr parent ):
Group(canvas, node, parent_style, parent) Group(canvas, node, parent_style, parent),
// TODO make projection configurable
_projection(new SansonFlamsteedProjection),
_projection_dirty(true)
{ {
staticInit(); staticInit();
projectionNodeChanged(node->getChild(PROJECTION));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -86,19 +78,17 @@ namespace canvas
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::updateImpl(double dt) void Map::update(double dt)
{ {
Group::updateImpl(dt); for( GeoNodes::iterator it = _geo_nodes.begin();
it != _geo_nodes.end();
for(auto& it: _geo_nodes) ++it )
{ {
GeoNodePair* geo_node = it.second.get(); GeoNodePair* geo_node = it->second.get();
if( !geo_node->isComplete() if( !geo_node->isComplete()
|| (!geo_node->isDirty() && !_projection_dirty) ) || (!geo_node->isDirty() && !_projection_dirty) )
continue; continue;
double latD = -9999.0, lonD = -9999.0;
if (geo_node->isDirty()) {
GeoCoord lat = parseGeoCoord(geo_node->getLat()); GeoCoord lat = parseGeoCoord(geo_node->getLat());
if( lat.type != GeoCoord::LATITUDE ) if( lat.type != GeoCoord::LATITUDE )
continue; continue;
@@ -107,28 +97,23 @@ namespace canvas
if( lon.type != GeoCoord::LONGITUDE ) if( lon.type != GeoCoord::LONGITUDE )
continue; continue;
// save the parsed values so we can re-use them if only projection Projection::ScreenPosition pos =
// is changed (very common case for moving vehicle) _projection->worldToScreen(lat.value, lon.value);
latD = lat.value;
lonD = lon.value;
geo_node->setCachedLatLon(std::make_pair(latD, lonD));
} else {
std::tie(latD, lonD) = geo_node->getCachedLatLon();
}
Projection::ScreenPosition pos = _projection->worldToScreen(latD, lonD);
geo_node->setScreenPos(pos.x, pos.y); geo_node->setScreenPos(pos.x, pos.y);
// geo_node->print(); // geo_node->print();
geo_node->setDirty(false); geo_node->setDirty(false);
} }
_projection_dirty = false; _projection_dirty = false;
Group::update(dt);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::childAdded(SGPropertyNode* parent, SGPropertyNode* child) void Map::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
{ {
if( strutils::ends_with(child->getNameString(), GEO) ) if( boost::ends_with(child->getNameString(), GEO) )
_geo_nodes[child].reset(new GeoNodePair()); _geo_nodes[child].reset(new GeoNodePair());
else if( parent != _node && child->getNameString() == HDG ) else if( parent != _node && child->getNameString() == HDG )
_hdg_nodes.insert(child); _hdg_nodes.insert(child);
@@ -139,7 +124,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::childRemoved(SGPropertyNode* parent, SGPropertyNode* child) void Map::childRemoved(SGPropertyNode* parent, SGPropertyNode* child)
{ {
if( strutils::ends_with(child->getNameString(), GEO) ) if( boost::ends_with(child->getNameString(), GEO) )
// TODO remove from other node // TODO remove from other node
_geo_nodes.erase(child); _geo_nodes.erase(child);
else if( parent != _node && child->getName() == HDG ) else if( parent != _node && child->getName() == HDG )
@@ -161,7 +146,7 @@ namespace canvas
{ {
const std::string& name = child->getNameString(); const std::string& name = child->getNameString();
if( strutils::ends_with(name, GEO) ) if( boost::ends_with(name, GEO) )
return geoNodeChanged(child); return geoNodeChanged(child);
else if( name == HDG ) else if( name == HDG )
return hdgNodeChanged(child); return hdgNodeChanged(child);
@@ -176,10 +161,10 @@ namespace canvas
if( child->getParent() != _node ) if( child->getParent() != _node )
return Group::childChanged(child); return Group::childChanged(child);
if( child->getNameString() == REF_LAT if( child->getNameString() == "ref-lat"
|| child->getNameString() == REF_LON ) || child->getNameString() == "ref-lon" )
_projection->setWorldPosition( _node->getDoubleValue(REF_LAT), _projection->setWorldPosition( _node->getDoubleValue("ref-lat"),
_node->getDoubleValue(REF_LON) ); _node->getDoubleValue("ref-lon") );
else if( child->getNameString() == HDG ) else if( child->getNameString() == HDG )
{ {
_projection->setOrientation(child->getFloatValue()); _projection->setOrientation(child->getFloatValue());
@@ -188,43 +173,16 @@ namespace canvas
++it ) ++it )
hdgNodeChanged(*it); hdgNodeChanged(*it);
} }
else if( child->getNameString() == RANGE ) else if( child->getNameString() == "range" )
_projection->setRange(child->getDoubleValue()); _projection->setRange(child->getDoubleValue());
else if( child->getNameString() == SCREEN_RANGE ) else if( child->getNameString() == "screen-range" )
_projection->setScreenRange(child->getDoubleValue()); _projection->setScreenRange(child->getDoubleValue());
else if( child->getNameString() == PROJECTION )
projectionNodeChanged(child);
else else
return Group::childChanged(child); return Group::childChanged(child);
_projection_dirty = true; _projection_dirty = true;
} }
//----------------------------------------------------------------------------
void Map::projectionNodeChanged(SGPropertyNode* child)
{
if(child && child->getStringValue() == WEB_MERCATOR)
_projection = std::make_shared<WebMercatorProjection>();
else
_projection = std::make_shared<SansonFlamsteedProjection>();
_projection->setWorldPosition(_node->getDoubleValue(REF_LAT),
_node->getDoubleValue(REF_LON));
// Only set existing properties to prevent using 0 instead of default values
if( auto heading = _node->getChild(HDG) )
_projection->setOrientation(heading->getFloatValue());
if( auto screen_range = _node->getChild(SCREEN_RANGE) )
_projection->setScreenRange(screen_range->getDoubleValue());
if( auto range = _node->getChild(RANGE) )
_projection->setRange(range->getDoubleValue());
_projection_dirty = true;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::geoNodeChanged(SGPropertyNode* child) void Map::geoNodeChanged(SGPropertyNode* child)
{ {
+26 -21
View File
@@ -1,6 +1,5 @@
///@file // A group of 2D Canvas elements which get automatically transformed according
/// A group of 2D Canvas elements which get automatically transformed according // to the map parameters.
/// to the map parameters.
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -23,9 +22,9 @@
#include "CanvasGroup.hxx" #include "CanvasGroup.hxx"
#include <memory> #include <boost/shared_ptr.hpp>
#include <unordered_map> #include <boost/unordered_map.hpp>
#include <unordered_set> #include <boost/unordered_set.hpp>
namespace simgear namespace simgear
{ {
@@ -46,37 +45,43 @@ namespace canvas
ElementWeakPtr parent = 0 ); ElementWeakPtr parent = 0 );
virtual ~Map(); virtual ~Map();
virtual void update(double dt);
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child );
virtual void valueChanged(SGPropertyNode * child);
protected: protected:
void updateImpl(double dt) override;
void updateProjection(SGPropertyNode* type_node); virtual void childChanged(SGPropertyNode * child);
void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override; typedef boost::unordered_map< SGPropertyNode*,
void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override; boost::shared_ptr<GeoNodePair>
void valueChanged(SGPropertyNode* child) override; > GeoNodes;
void childChanged(SGPropertyNode* child) override; typedef boost::unordered_set<SGPropertyNode*> NodeSet;
using GeoNodes =
std::unordered_map<SGPropertyNode*, std::shared_ptr<GeoNodePair>>;
using NodeSet = std::unordered_set<SGPropertyNode*>;
GeoNodes _geo_nodes; GeoNodes _geo_nodes;
NodeSet _hdg_nodes; NodeSet _hdg_nodes;
std::shared_ptr<HorizontalProjection> _projection; boost::shared_ptr<HorizontalProjection> _projection;
bool _projection_dirty = false; bool _projection_dirty;
struct GeoCoord struct GeoCoord
{ {
GeoCoord():
type(INVALID),
value(0)
{}
enum enum
{ {
INVALID, INVALID,
LATITUDE, LATITUDE,
LONGITUDE LONGITUDE
} type = INVALID; } type;
double value = 0; double value;
}; };
void projectionNodeChanged(SGPropertyNode* child);
void geoNodeChanged(SGPropertyNode * child); void geoNodeChanged(SGPropertyNode * child);
void hdgNodeChanged(SGPropertyNode * child); void hdgNodeChanged(SGPropertyNode * child);
+70 -397
View File
@@ -1,5 +1,4 @@
///@file // An OpenVG path on the Canvas
/// An OpenVG path on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,18 +16,14 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasPath.hxx" #include "CanvasPath.hxx"
#include <simgear/scene/util/parse_color.hxx> #include <simgear/scene/util/parse_color.hxx>
#include <simgear/misc/strutils.hxx>
#include <osg/Drawable> #include <osg/Drawable>
#include <osg/Version> #include <osg/Version>
#include <vg/openvg.h> #include <vg/openvg.h>
#include <cassert> #include <cassert>
#include <cctype>
namespace simgear namespace simgear
{ {
@@ -62,158 +57,21 @@ namespace canvas
*/ */
std::vector<float> splitAndConvert(const char del[], const std::string& str); std::vector<float> splitAndConvert(const char del[], const std::string& str);
static float parseCSSNumber(const std::string& s)
{
if (strutils::ends_with(s, "px")) {
return std::stof(s.substr(0, s.length() - 2));
} else if (s.back() == '%') {
float f = std::stof(s.substr(0, s.length() - 1));
return f / 100.0f;
}
return std::stof(s);
}
//----------------------------------------------------------------------------
static bool parseSVGPathToVGPath(const std::string& svgPath, CmdList& commands, CoordList& coords)
{
const string_list& tokens = simgear::strutils::split_on_any_of(svgPath, "\t \n\r,");
char activeSVGCommand = 0;
bool isRelative = false;
int tokensNeeded = 0;
for (auto it = tokens.begin(); it != tokens.end(); ) {
// set up the new command data
if ((it->size() == 1) && std::isalpha(it->at(0))) {
const char svgCommand = std::toupper(it->at(0));
isRelative = std::islower(it->at(0));
switch (svgCommand) {
case 'Z':
tokensNeeded = 0;
break;
case 'M':
case 'L':
case 'T':
tokensNeeded = 2;
break;
case 'H':
case 'V':
tokensNeeded = 1;
break;
case 'C':
tokensNeeded = 6;
break;
case 'S':
case 'Q':
tokensNeeded = 4;
break;
case 'A':
tokensNeeded = 7;
break;
default:
SG_LOG(SG_GENERAL, SG_WARN, "unrecognized SVG path command: "
<< *it << " at token " << std::distance(tokens.begin(), it));
return false;
}
activeSVGCommand = svgCommand;
++it; // advance to first coordinate token
}
const int numTokensRemaining = std::distance(it, tokens.end());
if (numTokensRemaining < tokensNeeded) {
SG_LOG(SG_GENERAL, SG_WARN, "insufficent SVG path tokens");
return false;
}
bool pushTokensDirectly = true;
if (activeSVGCommand == 'Z') {
commands.push_back(VG_CLOSE_PATH);
activeSVGCommand = 0;
} else if (activeSVGCommand == 'M') {
commands.push_back(VG_MOVE_TO | isRelative);
activeSVGCommand = 'L';
} else if (activeSVGCommand == 'L') {
commands.push_back(VG_LINE_TO | isRelative);
} else if (activeSVGCommand == 'H') {
commands.push_back(VG_HLINE_TO | isRelative);
} else if (activeSVGCommand == 'V') {
commands.push_back(VG_HLINE_TO | isRelative);
} else if (activeSVGCommand == 'C') {
commands.push_back(VG_CUBIC_TO | isRelative);
} else if (activeSVGCommand == 'S') {
commands.push_back(VG_SCUBIC_TO | isRelative);
} else if (activeSVGCommand == 'Q') {
commands.push_back(VG_SCUBIC_TO | isRelative);
} else if (activeSVGCommand == 'T') {
commands.push_back(VG_SCUBIC_TO | isRelative);
} else if (activeSVGCommand == 'A') {
pushTokensDirectly = false; // deal with tokens manually
coords.push_back(parseCSSNumber(*it++)); // rx
coords.push_back(parseCSSNumber(*it++)); // ry
coords.push_back(parseCSSNumber(*it++)); // x-axis rotation
const bool isLargeArc = std::stoi(*it++); // large-angle
const bool isCCW = std::stoi(*it++); // sweep-flag
int vgCmd = isLargeArc ? (isCCW ? VG_LCCWARC_TO : VG_LCWARC_TO) :
(isCCW ? VG_SCCWARC_TO : VG_SCWARC_TO);
coords.push_back(parseCSSNumber(*it++));
coords.push_back(parseCSSNumber(*it++));
commands.push_back(vgCmd | isRelative);
} else {
SG_LOG(SG_GENERAL, SG_WARN, "malformed SVG path string: expected a command at token:"
<< std::distance(tokens.begin(), it) << " :" << *it);
return false;
}
if (pushTokensDirectly) {
for (int i=0; i<tokensNeeded;++i) {
coords.push_back(parseCSSNumber(*it++));
}
}
} // of tokens iteration
return true;
}
//---------------------------------------------------------------------------
static SGVec2f parseRectCornerRadius(SGPropertyNode* node, const std::string& xDir, const std::string& yDir, bool& haveCorner)
{
haveCorner = false;
std::string propName = "border-" + yDir + "-" + xDir + "-radius";
if (!node->hasChild(propName)) {
propName = "border-" + yDir + "-radius";
if (!node->hasChild(propName)) {
propName = "border-radius";
}
}
PropertyList props = node->getChildren(propName);
if (props.size() == 1) {
double r = props.at(0)->getDoubleValue(propName);
haveCorner = true;
return SGVec2f(r, r);
}
if (props.size() >= 2 ) {
haveCorner = true;
return SGVec2f(props.at(0)->getDoubleValue(),
props.at(1)->getDoubleValue());
}
return SGVec2f(-1.0f, -1.0f);
}
//----------------------------------------------------------------------------
class Path::PathDrawable: class Path::PathDrawable:
public osg::Drawable public osg::Drawable
{ {
public: public:
PathDrawable(Path* path): PathDrawable(Path* path):
_path_element(path) _path_element(path),
_path(VG_INVALID_HANDLE),
_paint(VG_INVALID_HANDLE),
_paint_fill(VG_INVALID_HANDLE),
_attributes_dirty(~0),
_mode(0),
_fill_rule(VG_EVEN_ODD),
_stroke_width(1),
_stroke_linecap(VG_CAP_BUTT),
_stroke_linejoin(VG_JOIN_MITER)
{ {
setSupportsDisplayList(false); setSupportsDisplayList(false);
setDataVariance(Object::DYNAMIC); setDataVariance(Object::DYNAMIC);
@@ -231,12 +89,9 @@ namespace canvas
vgDestroyPaint(_paint_fill); vgDestroyPaint(_paint_fill);
} }
const char* className() const override virtual const char* className() const { return "PathDrawable"; }
{ return "PathDrawable"; } virtual osg::Object* cloneType() const { return new PathDrawable(_path_element); }
osg::Object* cloneType() const override virtual osg::Object* clone(const osg::CopyOp&) const { return new PathDrawable(_path_element); }
{ return new PathDrawable(_path_element); }
osg::Object* clone(const osg::CopyOp&) const override
{ return new PathDrawable(_path_element); }
/** /**
* Replace the current path segments with the new ones * Replace the current path segments with the new ones
@@ -277,16 +132,6 @@ namespace canvas
} }
} }
/**
* Set path fill opacity (Only used if fill is not "none")
*/
void setFillOpacity(float opacity)
{
_fill_opacity =
static_cast<uint8_t>(SGMiscf::clip(opacity, 0.f, 1.f) * 255);
_attributes_dirty |= FILL_COLOR;
}
/** /**
* Set path fill rule ("pseudo-nonzero" or "evenodd") * Set path fill rule ("pseudo-nonzero" or "evenodd")
* *
@@ -327,16 +172,6 @@ namespace canvas
} }
} }
/**
* Set path stroke opacity (only used if stroke is not "none")
*/
void setStrokeOpacity(float opacity)
{
_stroke_opacity =
static_cast<uint8_t>(SGMiscf::clip(opacity, 0.f, 1.f) * 255);
_attributes_dirty |= STROKE_COLOR;
}
/** /**
* Set stroke width * Set stroke width
*/ */
@@ -387,7 +222,7 @@ namespace canvas
/** /**
* Draw callback * Draw callback
*/ */
void drawImplementation(osg::RenderInfo& renderInfo) const override virtual void drawImplementation(osg::RenderInfo& renderInfo) const
{ {
if( _attributes_dirty & PATH ) if( _attributes_dirty & PATH )
return; return;
@@ -404,22 +239,31 @@ namespace canvas
osg::StateAttribute const* blend_func = osg::StateAttribute const* blend_func =
state->getLastAppliedAttribute(osg::StateAttribute::BLENDFUNC); state->getLastAppliedAttribute(osg::StateAttribute::BLENDFUNC);
// Setup paint
if( _mode & VG_STROKE_PATH )
{
// Initialize/Update the paint // Initialize/Update the paint
if( _attributes_dirty & STROKE_COLOR ) if( _attributes_dirty & STROKE_COLOR )
{ {
if( _paint == VG_INVALID_HANDLE ) if( _paint == VG_INVALID_HANDLE )
_paint = vgCreatePaint(); _paint = vgCreatePaint();
auto color = _stroke_color; vgSetParameterfv(_paint, VG_PAINT_COLOR, 4, _stroke_color._v);
color.a() *= _stroke_opacity / 255.f;
vgSetParameterfv(_paint, VG_PAINT_COLOR, 4, color._v);
_attributes_dirty &= ~STROKE_COLOR; _attributes_dirty &= ~STROKE_COLOR;
} }
// Initialize/update fill paint
if( _attributes_dirty & FILL_COLOR )
{
if( _paint_fill == VG_INVALID_HANDLE )
_paint_fill = vgCreatePaint();
vgSetParameterfv(_paint_fill, VG_PAINT_COLOR, 4, _fill_color._v);
_attributes_dirty &= ~FILL_COLOR;
}
// Setup paint
if( _mode & VG_STROKE_PATH )
{
vgSetPaint(_paint, VG_STROKE_PATH); vgSetPaint(_paint, VG_STROKE_PATH);
vgSetf(VG_STROKE_LINE_WIDTH, _stroke_width); vgSetf(VG_STROKE_LINE_WIDTH, _stroke_width);
@@ -431,19 +275,6 @@ namespace canvas
} }
if( _mode & VG_FILL_PATH ) if( _mode & VG_FILL_PATH )
{ {
// Initialize/update fill paint
if( _attributes_dirty & FILL_COLOR )
{
if( _paint_fill == VG_INVALID_HANDLE )
_paint_fill = vgCreatePaint();
auto color = _fill_color;
color.a() *= _fill_opacity / 255.f;
vgSetParameterfv(_paint_fill, VG_PAINT_COLOR, 4, color._v);
_attributes_dirty &= ~FILL_COLOR;
}
vgSetPaint(_paint_fill, VG_FILL_PATH); vgSetPaint(_paint_fill, VG_FILL_PATH);
vgSeti(VG_FILL_RULE, _fill_rule); vgSeti(VG_FILL_RULE, _fill_rule);
@@ -559,13 +390,13 @@ namespace canvas
/** /**
* Compute the bounding box * Compute the bounding box
*/ */
osg::BoundingBox virtual osg::BoundingBox
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
computeBound() computeBound()
#else #else
computeBoundingBox() computeBoundingBox()
#endif #endif
const override const
{ {
if( _path == VG_INVALID_HANDLE || (_attributes_dirty & PATH) ) if( _path == VG_INVALID_HANDLE || (_attributes_dirty & PATH) )
return osg::BoundingBox(); return osg::BoundingBox();
@@ -597,24 +428,22 @@ namespace canvas
Path *_path_element; Path *_path_element;
mutable VGPath _path {VG_INVALID_HANDLE}; mutable VGPath _path;
mutable VGPaint _paint {VG_INVALID_HANDLE}; mutable VGPaint _paint;
mutable VGPaint _paint_fill {VG_INVALID_HANDLE}; mutable VGPaint _paint_fill;
mutable uint32_t _attributes_dirty {~0u}; mutable uint32_t _attributes_dirty;
CmdList _cmds; CmdList _cmds;
CoordList _coords; CoordList _coords;
VGbitfield _mode {0}; VGbitfield _mode;
osg::Vec4f _fill_color; osg::Vec4f _fill_color;
uint8_t _fill_opacity {255}; VGFillRule _fill_rule;
VGFillRule _fill_rule {VG_EVEN_ODD};
osg::Vec4f _stroke_color; osg::Vec4f _stroke_color;
uint8_t _stroke_opacity {255}; VGfloat _stroke_width;
VGfloat _stroke_width {1};
std::vector<VGfloat> _stroke_dash; std::vector<VGfloat> _stroke_dash;
VGCapStyle _stroke_linecap {VG_CAP_BUTT}; VGCapStyle _stroke_linecap;
VGJoinStyle _stroke_linejoin {VG_JOIN_MITER}; VGJoinStyle _stroke_linejoin;
osg::Vec3f transformPoint( const osg::Matrix& m, osg::Vec3f transformPoint( const osg::Matrix& m,
osg::Vec2f pos ) const osg::Vec2f pos ) const
@@ -671,7 +500,7 @@ namespace canvas
struct PathUpdateCallback: struct PathUpdateCallback:
public osg::Drawable::UpdateCallback public osg::Drawable::UpdateCallback
{ {
void update(osg::NodeVisitor*, osg::Drawable* drawable) override virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
{ {
static_cast<PathDrawable*>(drawable)->update(); static_cast<PathDrawable*>(drawable)->update();
} }
@@ -690,10 +519,8 @@ namespace canvas
PathDrawableRef Path::*path = &Path::_path; PathDrawableRef Path::*path = &Path::_path;
addStyle("fill", "color", &PathDrawable::setFill, path); addStyle("fill", "color", &PathDrawable::setFill, path);
addStyle("fill-opacity", "numeric", &PathDrawable::setFillOpacity, path);
addStyle("fill-rule", "", &PathDrawable::setFillRule, path); addStyle("fill-rule", "", &PathDrawable::setFillRule, path);
addStyle("stroke", "color", &PathDrawable::setStroke, path); addStyle("stroke", "color", &PathDrawable::setStroke, path);
addStyle("stroke-opacity", "numeric", &PathDrawable::setStrokeOpacity, path);
addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path); addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path);
addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path); addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path);
addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path); addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path);
@@ -706,9 +533,7 @@ namespace canvas
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): ElementWeakPtr parent ):
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) ), _path( new PathDrawable(this) )
_hasSVG(false),
_hasRect(false)
{ {
staticInit(); staticInit();
@@ -722,69 +547,75 @@ namespace canvas
} }
//----------------------------------------------------------------------------
void Path::update(double dt)
{
if( _attributes_dirty & (CMDS | COORDS) )
{
_path->setSegments
(
_node->getChildValues<VGubyte, int>("cmd"),
_node->getChildValues<VGfloat, float>("coord")
);
_attributes_dirty &= ~(CMDS | COORDS);
}
Element::update(dt);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::BoundingBox Path::getTransformedBounds(const osg::Matrix& m) const osg::BoundingBox Path::getTransformedBounds(const osg::Matrix& m) const
{ {
return _path->getTransformedBounds(m); return _path->getTransformedBounds(m);
} }
//----------------------------------------------------------------------------
Path& Path::addSegment(uint8_t cmd, std::initializer_list<float> coords)
{
_node->addChild("cmd")->setIntValue(cmd);
for(float coord: coords)
_node->addChild("coord")->setFloatValue(coord);
return *this;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::moveTo(float x_abs, float y_abs) Path& Path::moveTo(float x_abs, float y_abs)
{ {
return addSegment(VG_MOVE_TO_ABS, {x_abs, y_abs}); return addSegment(VG_MOVE_TO_ABS, x_abs, y_abs);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::move(float x_rel, float y_rel) Path& Path::move(float x_rel, float y_rel)
{ {
return addSegment(VG_MOVE_TO_REL, {x_rel, y_rel}); return addSegment(VG_MOVE_TO_REL, x_rel, y_rel);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::lineTo(float x_abs, float y_abs) Path& Path::lineTo(float x_abs, float y_abs)
{ {
return addSegment(VG_LINE_TO_ABS, {x_abs, y_abs}); return addSegment(VG_LINE_TO_ABS, x_abs, y_abs);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::line(float x_rel, float y_rel) Path& Path::line(float x_rel, float y_rel)
{ {
return addSegment(VG_LINE_TO_REL, {x_rel, y_rel}); return addSegment(VG_LINE_TO_REL, x_rel, y_rel);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::horizTo(float x_abs) Path& Path::horizTo(float x_abs)
{ {
return addSegment(VG_HLINE_TO_ABS, {x_abs}); return addSegment(VG_HLINE_TO_ABS, x_abs);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::horiz(float x_rel) Path& Path::horiz(float x_rel)
{ {
return addSegment(VG_HLINE_TO_REL, {x_rel}); return addSegment(VG_HLINE_TO_REL, x_rel);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::vertTo(float y_abs) Path& Path::vertTo(float y_abs)
{ {
return addSegment(VG_VLINE_TO_ABS, {y_abs}); return addSegment(VG_VLINE_TO_ABS, y_abs);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path& Path::vert(float y_rel) Path& Path::vert(float y_rel)
{ {
return addSegment(VG_VLINE_TO_REL, {y_rel}); return addSegment(VG_VLINE_TO_REL, y_rel);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -799,111 +630,16 @@ namespace canvas
childChanged(child); childChanged(child);
} }
//----------------------------------------------------------------------------
void Path::setSVGPath(const std::string& svgPath)
{
_node->setStringValue("svg", svgPath);
_hasSVG = true;
_attributes_dirty |= SVG;
}
//----------------------------------------------------------------------------
void Path::setRect(const SGRect<float> &r)
{
_rect = r;
_hasRect = true;
_attributes_dirty |= RECT;
}
//----------------------------------------------------------------------------
void Path::setRoundRect(const SGRect<float> &r, float radiusX, float radiusY)
{
if (radiusY < 0.0) {
radiusY = radiusX;
}
setRect(r);
_node->getChild("border-radius", 0, true)->setDoubleValue(radiusX);
_node->getChild("border-radius", 1, true)->setDoubleValue(radiusY);
}
//----------------------------------------------------------------------------
void Path::updateImpl(double dt)
{
Element::updateImpl(dt);
if( _attributes_dirty & (CMDS | COORDS) )
{
_path->setSegments
(
_node->getChildValues<VGubyte, int>("cmd"),
_node->getChildValues<VGfloat, float>("coord")
);
_attributes_dirty &= ~(CMDS | COORDS);
}
// SVG path overrides manual cmd/coord specification
if( _hasSVG && (_attributes_dirty & SVG) )
{
CmdList cmds;
CoordList coords;
parseSVGPathToVGPath(_node->getStringValue("svg"), cmds, coords);
_path->setSegments(cmds, coords);
_attributes_dirty &= ~SVG;
}
if( _hasRect &&(_attributes_dirty & RECT) )
{
parseRectToVGPath();
_attributes_dirty &= ~RECT;
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Path::childChanged(SGPropertyNode* child) void Path::childChanged(SGPropertyNode* child)
{ {
if( child->getParent() != _node ) if( child->getParent() != _node )
return; return;
const std::string& name = child->getNameString(); if( child->getNameString() == "cmd" )
const std::string &prName = child->getParent()->getNameString();
if( strutils::starts_with(name, "border-") )
{
_attributes_dirty |= RECT;
return;
}
if (prName == "rect")
{
_hasRect = true;
if (name == "left") {
_rect.setLeft(child->getDoubleValue());
} else if (name == "top") {
_rect.setTop(child->getDoubleValue());
} else if (name == "right") {
_rect.setRight(child->getDoubleValue());
} else if (name == "bottom") {
_rect.setBottom(child->getDoubleValue());
} else if (name == "width") {
_rect.setWidth(child->getDoubleValue());
} else if (name == "height") {
_rect.setHeight(child->getDoubleValue());
}
_attributes_dirty |= RECT;
return;
}
if( name == "cmd" )
_attributes_dirty |= CMDS; _attributes_dirty |= CMDS;
else if( name == "coord" ) else if( child->getNameString() == "coord" )
_attributes_dirty |= COORDS; _attributes_dirty |= COORDS;
else if ( name == "svg")
{
_hasSVG = true;
_attributes_dirty |= SVG;
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -928,68 +664,5 @@ namespace canvas
return values; return values;
} }
//----------------------------------------------------------------------------
void operator+=(CoordList& base, const std::initializer_list<VGfloat>& other)
{
base.insert(base.end(), other.begin(), other.end());
}
//----------------------------------------------------------------------------
void Path::parseRectToVGPath()
{
CmdList commands;
CoordList coords;
commands.reserve(4);
coords.reserve(8);
bool haveCorner = false;
SGVec2f topLeft = parseRectCornerRadius(_node, "left", "top", haveCorner);
if (haveCorner) {
commands.push_back(VG_MOVE_TO_ABS);
coords += {_rect.l(), _rect.t() + topLeft.y()};
commands.push_back(VG_SCCWARC_TO_REL);
coords += {topLeft.x(), topLeft.y(), 0.0, topLeft.x(), -topLeft.y()};
} else {
commands.push_back(VG_MOVE_TO_ABS);
coords += {_rect.l(), _rect.t()};
}
SGVec2f topRight = parseRectCornerRadius(_node, "right", "top", haveCorner);
if (haveCorner) {
commands.push_back(VG_HLINE_TO_ABS);
coords += {_rect.r() - topRight.x()};
commands.push_back(VG_SCCWARC_TO_REL);
coords += {topRight.x(), topRight.y(), 0.0, topRight.x(), topRight.y()};
} else {
commands.push_back(VG_HLINE_TO_ABS);
coords += {_rect.r()};
}
SGVec2f bottomRight = parseRectCornerRadius(_node, "right", "bottom", haveCorner);
if (haveCorner) {
commands.push_back(VG_VLINE_TO_ABS);
coords += {_rect.b() - bottomRight.y()};
commands.push_back(VG_SCCWARC_TO_REL);
coords += {bottomRight.x(), bottomRight.y(), 0.0, -bottomRight.x(), bottomRight.y()};
} else {
commands.push_back(VG_VLINE_TO_ABS);
coords += {_rect.b()};
}
SGVec2f bottomLeft = parseRectCornerRadius(_node, "left", "bottom", haveCorner);
if (haveCorner) {
commands.push_back(VG_HLINE_TO_ABS);
coords += {_rect.l() + bottomLeft.x()};
commands.push_back(VG_SCCWARC_TO_REL);
coords += {bottomLeft.x(), bottomLeft.y(), 0.0, -bottomLeft.x(), -bottomLeft.y()};
} else {
commands.push_back(VG_HLINE_TO_ABS);
coords += {_rect.l()};
}
commands.push_back(VG_CLOSE_PATH);
_path->setSegments(commands, coords);
}
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+13 -26
View File
@@ -1,5 +1,4 @@
///@file // An OpenVG path on the Canvas
/// An OpenVG path on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -21,8 +20,7 @@
#define CANVAS_PATH_HXX_ #define CANVAS_PATH_HXX_
#include "CanvasElement.hxx" #include "CanvasElement.hxx"
#include <simgear/math/SGRect.hxx> #include <boost/preprocessor/iteration/iterate.hpp>
#include <initializer_list>
namespace simgear namespace simgear
{ {
@@ -41,11 +39,14 @@ namespace canvas
ElementWeakPtr parent = 0 ); ElementWeakPtr parent = 0 );
virtual ~Path(); virtual ~Path();
osg::BoundingBox virtual void update(double dt);
getTransformedBounds(const osg::Matrix& m) const override;
/** Add a segment with the given command and coordinates */ virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
Path& addSegment(uint8_t cmd, std::initializer_list<float> coords = {});
#define BOOST_PP_ITERATION_LIMITS (0, 6)
#define BOOST_PP_FILENAME_1 \
<simgear/canvas/elements/detail/add_segment_variadic.hxx>
#include BOOST_PP_ITERATE()
/** Move path cursor */ /** Move path cursor */
Path& moveTo(float x_abs, float y_abs); Path& moveTo(float x_abs, float y_abs);
@@ -66,34 +67,20 @@ namespace canvas
/** Close the path (implicit lineTo to first point of path) */ /** Close the path (implicit lineTo to first point of path) */
Path& close(); Path& close();
void setSVGPath(const std::string& svgPath);
void setRect(const SGRectf& r);
void setRoundRect(const SGRectf& r, float radiusX, float radiusY = -1.0);
protected: protected:
enum PathAttributes enum PathAttributes
{ {
CMDS = LAST_ATTRIBUTE << 1, CMDS = LAST_ATTRIBUTE << 1,
COORDS = CMDS << 1, COORDS = CMDS << 1
SVG = COORDS << 1,
RECT = SVG << 1
}; };
class PathDrawable; class PathDrawable;
typedef osg::ref_ptr<PathDrawable> PathDrawableRef; typedef osg::ref_ptr<PathDrawable> PathDrawableRef;
PathDrawableRef _path; PathDrawableRef _path;
bool _hasSVG : 1; virtual void childRemoved(SGPropertyNode * child);
bool _hasRect : 1; virtual void childChanged(SGPropertyNode * child);
SGRectf _rect;
void updateImpl(double dt) override;
void childRemoved(SGPropertyNode * child) override;
void childChanged(SGPropertyNode * child) override;
void parseRectToVGPath();
}; };
} // namespace canvas } // namespace canvas
+22 -79
View File
@@ -1,5 +1,4 @@
///@file // A text on the Canvas
/// A text on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CanvasText.hxx" #include "CanvasText.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasSystemAdapter.hxx> #include <simgear/canvas/CanvasSystemAdapter.hxx>
@@ -53,30 +50,26 @@ namespace canvas
TextLine lineAt(size_t i) const; TextLine lineAt(size_t i) const;
/// Get nearest line to given y-coordinate /// Get nearest line to given y-coordinate
#if OSG_VERSION_LESS_THAN(3,6,5)
TextLine nearestLine(float pos_y) const; TextLine nearestLine(float pos_y) const;
SGVec2i sizeForWidth(int w) const;
#else
TextLine nearestLine(float pos_y);
SGVec2i sizeForWidth(int w);
#endif
SGVec2i sizeForWidth(int w) const;
virtual osg::BoundingBox
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
osg::BoundingBox computeBound() const override; computeBound()
#else #else
osg::BoundingBox computeBoundingBox() const override; computeBoundingBox()
#endif #endif
const;
protected: protected:
friend class TextLine; friend class TextLine;
canvas::Text *_text_element; canvas::Text *_text_element;
#if OSG_VERSION_LESS_THAN(3,5,6) virtual void computePositions(unsigned int contextID) const;
void computePositions(unsigned int contextID) const override;
#else
void computePositionsImplementation() override;
#endif
}; };
class TextLine class TextLine
@@ -127,7 +120,6 @@ namespace canvas
_quads = &text->_textureGlyphQuadMap.begin()->second; _quads = &text->_textureGlyphQuadMap.begin()->second;
#if OSG_VERSION_LESS_THAN(3,5,6)
GlyphQuads::LineNumbers const& line_numbers = _quads->_lineNumbers; GlyphQuads::LineNumbers const& line_numbers = _quads->_lineNumbers;
GlyphQuads::LineNumbers::const_iterator begin_it = GlyphQuads::LineNumbers::const_iterator begin_it =
std::lower_bound(line_numbers.begin(), line_numbers.end(), _line); std::lower_bound(line_numbers.begin(), line_numbers.end(), _line);
@@ -139,9 +131,6 @@ namespace canvas
_begin = begin_it - line_numbers.begin(); _begin = begin_it - line_numbers.begin();
_end = std::upper_bound(begin_it, line_numbers.end(), _line) _end = std::upper_bound(begin_it, line_numbers.end(), _line)
- line_numbers.begin(); - line_numbers.begin();
#else
// TODO: Need 3.5.6 version of this
#endif
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -170,17 +159,12 @@ namespace canvas
if( empty() ) if( empty() )
return pos; return pos;
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,6)
// TODO: need 3.5.6 version of this.
#else
#if OSG_VERSION_LESS_THAN(3,3,5) #if OSG_VERSION_LESS_THAN(3,3,5)
GlyphQuads::Coords2 const& coords = _quads->_coords; GlyphQuads::Coords2 const& coords = _quads->_coords;
#else #else
GlyphQuads::Coords2 refCoords = _quads->_coords; GlyphQuads::Coords2 refCoords = _quads->_coords;
GlyphQuads::Coords2::element_type &coords = *refCoords.get(); GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif #endif
size_t global_i = _begin + i; size_t global_i = _begin + i;
if( global_i == _begin ) if( global_i == _begin )
@@ -203,7 +187,6 @@ namespace canvas
// position at center between characters // position at center between characters
pos.x() = 0.5 * (prev_r + cur_l); pos.x() = 0.5 * (prev_r + cur_l);
} }
#endif
return pos; return pos;
} }
@@ -214,10 +197,7 @@ namespace canvas
if( empty() ) if( empty() )
return cursorPos(0); return cursorPos(0);
#if OSG_VERSION_GREATER_OR_EQUAL(3,5,6) GlyphQuads::Glyphs const& glyphs = _quads->_glyphs;
// TODO: need 3.5.7 version of this.
return cursorPos(0);
#else
#if OSG_VERSION_LESS_THAN(3,3,5) #if OSG_VERSION_LESS_THAN(3,3,5)
GlyphQuads::Coords2 const& coords = _quads->_coords; GlyphQuads::Coords2 const& coords = _quads->_coords;
#else #else
@@ -225,8 +205,6 @@ namespace canvas
GlyphQuads::Coords2::element_type &coords = *refCoords.get(); GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif #endif
GlyphQuads::Glyphs const& glyphs = _quads->_glyphs;
float const HIT_FRACTION = 0.6; float const HIT_FRACTION = 0.6;
float const character_width = _text->getCharacterHeight() float const character_width = _text->getCharacterHeight()
* _text->getCharacterAspectRatio(); * _text->getCharacterAspectRatio();
@@ -245,7 +223,6 @@ namespace canvas
} }
return cursorPos(i - _begin); return cursorPos(i - _begin);
#endif
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -324,16 +301,9 @@ namespace canvas
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#if OSG_VERSION_LESS_THAN(3,6,5)
TextLine Text::TextOSG::nearestLine(float pos_y) const TextLine Text::TextOSG::nearestLine(float pos_y) const
{ {
osgText::Font const* font = getActiveFont(); osgText::Font const* font = getActiveFont();
#else
TextLine Text::TextOSG::nearestLine(float pos_y)
{
auto font = getActiveFont();
#endif
if( !font || lineCount() <= 0 ) if( !font || lineCount() <= 0 )
return TextLine(0, this); return TextLine(0, this);
@@ -355,21 +325,12 @@ namespace canvas
// simplified version of osgText::Text::computeGlyphRepresentation() to // simplified version of osgText::Text::computeGlyphRepresentation() to
// just calculate the size for a given weight. Glpyh calculations/creating // just calculate the size for a given weight. Glpyh calculations/creating
// is not necessary for this... // is not necessary for this...
#if OSG_VERSION_LESS_THAN(3,6,5)
SGVec2i Text::TextOSG::sizeForWidth(int w) const SGVec2i Text::TextOSG::sizeForWidth(int w) const
#else
SGVec2i Text::TextOSG::sizeForWidth(int w)
#endif
{ {
if( _text.empty() ) if( _text.empty() )
return SGVec2i(0, 0); return SGVec2i(0, 0);
#if OSG_VERSION_LESS_THAN(3,6,5)
osgText::Font* activefont = const_cast<osgText::Font*>(getActiveFont()); osgText::Font* activefont = const_cast<osgText::Font*>(getActiveFont());
#else
auto activefont = getActiveFont();
#endif
if( !activefont ) if( !activefont )
return SGVec2i(-1, -1); return SGVec2i(-1, -1);
@@ -535,31 +496,18 @@ namespace canvas
{ {
case LEFT_TO_RIGHT: case LEFT_TO_RIGHT:
{ {
#if OSG_VERSION_LESS_THAN(3,5,2)
osg::Vec2 delta( activefont->getKerning( previous_charcode, osg::Vec2 delta( activefont->getKerning( previous_charcode,
charcode, charcode,
_kerningType ) ); _kerningType ) );
#else
osg::Vec2 delta(activefont->getKerning(_fontSize,
previous_charcode,
charcode,
_kerningType));
#endif
cursor.x() += delta.x() * wr; cursor.x() += delta.x() * wr;
cursor.y() += delta.y() * hr; cursor.y() += delta.y() * hr;
break; break;
} }
case RIGHT_TO_LEFT: case RIGHT_TO_LEFT:
{ {
#if OSG_VERSION_LESS_THAN(3,5,2)
osg::Vec2 delta( activefont->getKerning( charcode, osg::Vec2 delta( activefont->getKerning( charcode,
previous_charcode, previous_charcode,
_kerningType ) ); _kerningType ) );
#else
osg::Vec2 delta(activefont->getKerning(_fontSize, charcode,
previous_charcode,
_kerningType));
#endif
cursor.x() -= delta.x() * wr; cursor.x() -= delta.x() * wr;
cursor.y() -= delta.y() * hr; cursor.y() -= delta.y() * hr;
break; break;
@@ -649,16 +597,19 @@ namespace canvas
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::BoundingBox
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
osg::BoundingBox Text::TextOSG::computeBound() const Text::TextOSG::computeBound()
#else #else
osg::BoundingBox Text::TextOSG::computeBoundingBox() const Text::TextOSG::computeBoundingBox()
#endif #endif
const
{ {
osg::BoundingBox bb =
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
osg::BoundingBox bb = osgText::Text::computeBound(); osgText::Text::computeBound();
#else #else
osg::BoundingBox bb = osgText::Text::computeBoundingBox(); osgText::Text::computeBoundingBox();
#endif #endif
#if OSG_VERSION_LESS_THAN(3,1,0) #if OSG_VERSION_LESS_THAN(3,1,0)
@@ -674,7 +625,7 @@ namespace canvas
return bb; return bb;
} }
#if OSG_VERSION_LESS_THAN(3,5,6) //----------------------------------------------------------------------------
void Text::TextOSG::computePositions(unsigned int contextID) const void Text::TextOSG::computePositions(unsigned int contextID) const
{ {
if( _textureGlyphQuadMap.empty() || _layout == VERTICAL ) if( _textureGlyphQuadMap.empty() || _layout == VERTICAL )
@@ -744,14 +695,6 @@ namespace canvas
return osgText::Text::computePositions(contextID); return osgText::Text::computePositions(contextID);
} }
#else
void Text::TextOSG::computePositionsImplementation()
{
TextBase::computePositionsImplementation();
}
#endif
//----------------------------------------------------------------------------
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string Text::TYPE_NAME = "text"; const std::string Text::TYPE_NAME = "text";
@@ -908,12 +851,12 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
osg::StateSet* Text::getOrCreateStateSet() osg::StateSet* Text::getOrCreateStateSet()
{ {
if( !_scene_group.valid() ) if( !_transform.valid() )
return nullptr; return 0;
// Only check for StateSet on Transform, as the text stateset is shared // Only check for StateSet on Transform, as the text stateset is shared
// between all text instances using the same font (texture). // between all text instances using the same font (texture).
return _scene_group->getOrCreateStateSet(); return _transform->getOrCreateStateSet();
} }
} // namespace canvas } // namespace canvas
+1 -2
View File
@@ -1,5 +1,4 @@
///@file // A text on the Canvas
/// A text on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -0,0 +1,21 @@
#ifndef CANVAS_PATH_HXX_
# error Canvas - do not include this file!
#endif
#define n BOOST_PP_ITERATION()
Path& addSegment( uint8_t cmd
BOOST_PP_COMMA_IF(n)
BOOST_PP_ENUM_PARAMS(n, float coord) )
{
_node->addChild("cmd")->setIntValue(cmd);
#define SG_CANVAS_PATH_SET_COORD(z, n, dummy)\
_node->addChild("coord")->setFloatValue(coord##n);
BOOST_PP_REPEAT(n, SG_CANVAS_PATH_SET_COORD, 0)
#undef SG_CANVAS_PATH_SET_COORD
return *this;
}
#undef n
+4 -24
View File
@@ -67,7 +67,6 @@ namespace canvas
{ {
_node_lat = node; _node_lat = node;
_status &= ~LAT_MISSING; _status &= ~LAT_MISSING;
_xNode.reset();
if( node == _node_lon ) if( node == _node_lon )
{ {
@@ -80,7 +79,6 @@ namespace canvas
{ {
_node_lon = node; _node_lon = node;
_status &= ~LON_MISSING; _status &= ~LON_MISSING;
_yNode.reset();
if( node == _node_lat ) if( node == _node_lat )
{ {
@@ -99,34 +97,19 @@ namespace canvas
return _node_lon ? _node_lon->getStringValue() : ""; return _node_lon ? _node_lon->getStringValue() : "";
} }
void setCachedLatLon(const std::pair<double, double>& latLon)
{ _cachedLatLon = latLon; }
std::pair<double, double> getCachedLatLon()
{ return _cachedLatLon; }
void setTargetName(const std::string& name) void setTargetName(const std::string& name)
{ {
_target_name = name; _target_name = name;
_xNode.reset();
_yNode.reset();
} }
void setScreenPos(float x, float y) void setScreenPos(float x, float y)
{ {
assert( isComplete() ); assert( isComplete() );
if (!_xNode) {
SGPropertyNode *parent = _node_lat->getParent(); SGPropertyNode *parent = _node_lat->getParent();
_xNode = parent->getChild(_target_name, _node_lat->getIndex(), true); parent->getChild(_target_name, _node_lat->getIndex(), true)
} ->setDoubleValue(x);
parent->getChild(_target_name, _node_lon->getIndex(), true)
if (!_yNode) { ->setDoubleValue(y);
SGPropertyNode *parent = _node_lat->getParent();
_yNode = parent->getChild(_target_name, _node_lon->getIndex(), true);
}
_xNode->setDoubleValue(x);
_yNode->setDoubleValue(y);
} }
void print() void print()
@@ -142,9 +125,6 @@ namespace canvas
SGPropertyNode *_node_lat, SGPropertyNode *_node_lat,
*_node_lon; *_node_lon;
std::string _target_name; std::string _target_name;
SGPropertyNode_ptr _xNode,
_yNode;
std::pair<double, double> _cachedLatLon;
}; };
+1 -28
View File
@@ -1,5 +1,4 @@
///@file // Geographic projections for Canvas map element
/// Geographic projections for Canvas map element
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -191,32 +190,6 @@ namespace canvas
} }
}; };
/**
* WebMercator projection, relative to the projection center.
* Required for Slippy Maps - i.e. openstreetmap
*/
class WebMercatorProjection:
public HorizontalProjection
{
protected:
virtual ScreenPosition project(double lat, double lon) const
{
double d_lat = lat - _ref_lat,
d_lon = lon - _ref_lon;
double r = 6378137.f / 1852; // Equatorial radius divided by ?
ScreenPosition pos;
pos.x = r * d_lon;
pos.y = r * (log(tan(d_lat) + 1.0 / cos(d_lat)));
//pos.x = lon;
//pos.y = log(tan(lat) + 1.0 / cos(lat));
return pos;
}
};
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+1 -11
View File
@@ -1,5 +1,4 @@
///@file // Canvas user defined event
/// Canvas user defined event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,7 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "CustomEvent.hxx" #include "CustomEvent.hxx"
namespace simgear namespace simgear
@@ -47,14 +45,6 @@ namespace canvas
// assert( type_map.find(type_id) != type_map.end() ); // assert( type_map.find(type_id) != type_map.end() );
} }
//----------------------------------------------------------------------------
CustomEvent* CustomEvent::clone(int type) const
{
auto event = new CustomEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void CustomEvent::setDetail(StringMap const& data) void CustomEvent::setDetail(StringMap const& data)
{ {
+1 -8
View File
@@ -38,7 +38,6 @@ namespace canvas
public: public:
/** /**
* @brief Construct a user defined event from a type string
* *
* @param type_str Event type name (if name does not exist yet it will * @param type_str Event type name (if name does not exist yet it will
* be registered as new event type) * be registered as new event type)
@@ -50,10 +49,6 @@ namespace canvas
StringMap const& data = StringMap() ); StringMap const& data = StringMap() );
/** /**
* @brief Construct a user defined event from a (previously registered)
* type id
*
* @see getOrRegisterType()
* *
* @param type_id Event type id * @param type_id Event type id
* @param bubbles If this event should take part in the bubbling phase * @param bubbles If this event should take part in the bubbling phase
@@ -63,8 +58,6 @@ namespace canvas
bool bubbles = false, bool bubbles = false,
StringMap const& data = StringMap() ); StringMap const& data = StringMap() );
CustomEvent* clone(int type = 0) const override;
/** /**
* Set user data * Set user data
*/ */
@@ -81,7 +74,7 @@ namespace canvas
* @see #bubbles * @see #bubbles
* @see CustomEvent() * @see CustomEvent()
*/ */
bool canBubble() const override { return bubbles; } virtual bool canBubble() const { return bubbles; }
StringMap detail; //!< User data map StringMap detail; //!< User data map
bool bubbles; //!< Whether the event supports bubbling bool bubbles; //!< Whether the event supports bubbling
+1 -4
View File
@@ -1,5 +1,4 @@
///@file // Input device event
/// Input device event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "DeviceEvent.hxx" #include "DeviceEvent.hxx"
#include <osgGA/GUIEventAdapter> #include <osgGA/GUIEventAdapter>
+7 -51
View File
@@ -1,5 +1,4 @@
///@file // Keyboard event
/// Keyboard event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,9 +16,8 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "KeyboardEvent.hxx" #include "KeyboardEvent.hxx"
#include "utf8.h"
#include <osgGA/GUIEventAdapter> #include <osgGA/GUIEventAdapter>
@@ -43,7 +41,6 @@ namespace canvas
// TODO check Win/Mac keycode for altgr/ISO Level3 Shift // TODO check Win/Mac keycode for altgr/ISO Level3 Shift
const uint32_t KEY_AltGraph = 0xfe03; const uint32_t KEY_AltGraph = 0xfe03;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
KeyboardEvent::KeyboardEvent(): KeyboardEvent::KeyboardEvent():
_key(0), _key(0),
@@ -70,14 +67,6 @@ namespace canvas
// // TODO what to do with wrong event type? // // TODO what to do with wrong event type?
} }
//----------------------------------------------------------------------------
KeyboardEvent* KeyboardEvent::clone(int type) const
{
auto event = new KeyboardEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void KeyboardEvent::setKey(uint32_t key) void KeyboardEvent::setKey(uint32_t key)
{ {
@@ -278,24 +267,10 @@ namespace canvas
// Empty or no mapping -> convert UTF-32 key value to UTF-8 // Empty or no mapping -> convert UTF-32 key value to UTF-8
if( _name.empty() ) if( _name.empty() )
{ {
if (( _key >= 0xd800u && _key <= 0xdfffu ) || _key > 0x10ffffu ) if( !utf8::internal::is_code_point_valid(_key) )
_name = "Unidentified"; _name = "Unidentified";
else else
if ( _key <= 0x7f ) { utf8::unchecked::append(_key, std::back_inserter(_name));
_name.push_back(static_cast<uint8_t>(_key));
} else if ( _key <= 0x7ff ) {
_name.push_back(static_cast<uint8_t>((_key >> 6) | 0xc0));
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
} else if ( _key <= 0xffff ) {
_name.push_back(static_cast<uint8_t>((_key >> 12) | 0xe0));
_name.push_back(static_cast<uint8_t>(((_key >> 6) & 0x3f) | 0x80));
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
} else {
_name.push_back(static_cast<uint8_t>((_key >> 18) | 0xf0));
_name.push_back(static_cast<uint8_t>(((_key >> 12) & 0x3f) | 0x80));
_name.push_back(static_cast<uint8_t>(((_key >> 6) & 0x3f) | 0x80));
_name.push_back(static_cast<uint8_t>((_key & 0x3f) | 0x80));
}
} }
// Keys on the numpad with NumLock enabled are reported just like their // Keys on the numpad with NumLock enabled are reported just like their
@@ -330,30 +305,11 @@ namespace canvas
if( key_name.empty() ) if( key_name.empty() )
return false; return false;
// Convert the key name to the corresponding code point by checking the std::string::const_iterator it = key_name.begin();
// sequence length (the first bits of the first byte) and performing the uint32_t cp = utf8::next(it, key_name.end());
// conversion accordingly.
uint32_t cp = key_name[0] & 0xff;
size_t len;
if (cp < 0x80) {
len = 1;
} else if ((cp >> 5) == 0x6) {
cp = ((cp << 6) & 0x7ff) + (key_name[1] & 0x3f);
len = 2;
} else if ((cp >> 4) == 0xe) {
cp = ((cp << 12) & 0xffff) + (((key_name[1] & 0xff) << 6) & 0xfff)
+ (key_name[2] & 0x3f);
len = 3;
} else if ((cp >> 3) == 0x1e) {
cp = ((cp << 18) & 0x1fffff) + (((key_name[1] & 0xff) << 12) & 0x3ffff)
+ (((key_name[2] & 0xff) << 6) & 0xfff) + (key_name[3] & 0x3f);
len = 4;
} else {
return false;
}
// Check if _name contains exactly one (UTF-8 encoded) character. // Check if _name contains exactly one (UTF-8 encoded) character.
if (key_name.length() > len) if( it != key_name.end() )
return false; return false;
// C0 and C1 control characters are not printable. // C0 and C1 control characters are not printable.
-1
View File
@@ -45,7 +45,6 @@ namespace canvas
KeyboardEvent(); KeyboardEvent();
KeyboardEvent(const osgGA::GUIEventAdapter& ea); KeyboardEvent(const osgGA::GUIEventAdapter& ea);
KeyboardEvent* clone(int type = 0) const override;
void setKey(uint32_t key); void setKey(uint32_t key);
void setUnmodifiedKey(uint32_t key); void setUnmodifiedKey(uint32_t key);
+1 -12
View File
@@ -1,5 +1,4 @@
///@file // Mouse event
/// Mouse event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "MouseEvent.hxx" #include "MouseEvent.hxx"
#include <osgGA/GUIEventAdapter> #include <osgGA/GUIEventAdapter>
@@ -49,14 +46,6 @@ namespace canvas
button += 1; button += 1;
} }
//----------------------------------------------------------------------------
MouseEvent* MouseEvent::clone(int type) const
{
auto event = new MouseEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool MouseEvent::canBubble() const bool MouseEvent::canBubble() const
{ {
+1 -2
View File
@@ -36,9 +36,8 @@ namespace canvas
public: public:
MouseEvent(); MouseEvent();
MouseEvent(const osgGA::GUIEventAdapter& ea); MouseEvent(const osgGA::GUIEventAdapter& ea);
MouseEvent* clone(int type = 0) const override;
bool canBubble() const override; virtual bool canBubble() const;
osg::Vec2f getScreenPos() const { return screen_pos; } osg::Vec2f getScreenPos() const { return screen_pos; }
osg::Vec2f getClientPos() const { return client_pos; } osg::Vec2f getClientPos() const { return client_pos; }
+1 -4
View File
@@ -1,5 +1,4 @@
///@file // Keyboard event demo. Press some keys and get some info...
/// Keyboard event demo. Press some keys and get some info...
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "KeyboardEvent.hxx" #include "KeyboardEvent.hxx"
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
+1 -3
View File
@@ -16,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "BoxLayout.hxx" #include "BoxLayout.hxx"
#include "SpacerItem.hxx" #include "SpacerItem.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
@@ -73,7 +71,7 @@ namespace canvas
int stretch, int stretch,
uint8_t alignment ) uint8_t alignment )
{ {
ItemData item_data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ItemData item_data = {0};
item_data.layout_item = item; item_data.layout_item = item;
item_data.stretch = std::max(0, stretch); item_data.stretch = std::max(0, stretch);
-4
View File
@@ -16,11 +16,7 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "Layout.hxx" #include "Layout.hxx"
#include <algorithm>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
namespace simgear namespace simgear
-1
View File
@@ -16,7 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "LayoutItem.hxx" #include "LayoutItem.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
+14 -15
View File
@@ -16,8 +16,6 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h>
#include "NasalWidget.hxx" #include "NasalWidget.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
@@ -45,7 +43,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
NasalWidget::~NasalWidget() NasalWidget::~NasalWidget()
{ {
onRemove();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -150,7 +148,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool NasalWidget::hasHeightForWidth() const bool NasalWidget::hasHeightForWidth() const
{ {
return _height_for_width || _min_height_for_width; return !_height_for_width.empty() || !_min_height_for_width.empty();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -186,13 +184,13 @@ namespace canvas
int NasalWidget::callHeightForWidthFunc( const HeightForWidthFunc& hfw, int NasalWidget::callHeightForWidthFunc( const HeightForWidthFunc& hfw,
int w ) const int w ) const
{ {
if( !hfw ) if( hfw.empty() )
return -1; return -1;
naContext c = naNewContext();
try try
{ {
nasal::Context ctx; return hfw(nasal::to_nasal(c, const_cast<NasalWidget*>(this)), w);
return hfw(ctx.to_me(const_cast<NasalWidget*>(this)), w);
} }
catch( std::exception const& ex ) catch( std::exception const& ex )
{ {
@@ -202,6 +200,7 @@ namespace canvas
"NasalWidget.heightForWidth: callback error: '" << ex.what() << "'" "NasalWidget.heightForWidth: callback error: '" << ex.what() << "'"
); );
} }
naFreeContext(c);
return -1; return -1;
} }
@@ -239,17 +238,17 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int NasalWidget::heightForWidthImpl(int w) const int NasalWidget::heightForWidthImpl(int w) const
{ {
return callHeightForWidthFunc( _height_for_width return callHeightForWidthFunc( _height_for_width.empty()
? _height_for_width ? _min_height_for_width
: _min_height_for_width, w ); : _height_for_width, w );
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int NasalWidget::minimumHeightForWidthImpl(int w) const int NasalWidget::minimumHeightForWidthImpl(int w) const
{ {
return callHeightForWidthFunc( _min_height_for_width return callHeightForWidthFunc( _min_height_for_width.empty()
? _min_height_for_width ? _height_for_width
: _height_for_width, w ); : _min_height_for_width, w );
} }
@@ -261,8 +260,8 @@ namespace canvas
try try
{ {
nasal::Context ctx; nasal::Context c;
_set_geometry(ctx.to_me(this), rect); _set_geometry(nasal::to_nasal(c, this), rect);
_flags &= ~LAYOUT_DIRTY; _flags &= ~LAYOUT_DIRTY;
} }
catch( std::exception const& ex ) catch( std::exception const& ex )
+2 -2
View File
@@ -40,8 +40,8 @@ namespace canvas
{ {
public: public:
typedef std::function<void (nasal::Me, const SGRecti&)> SetGeometryFunc; typedef boost::function<void (nasal::Me, const SGRecti&)> SetGeometryFunc;
typedef std::function<int (nasal::Me, int)> HeightForWidthFunc; typedef boost::function<int (nasal::Me, int)> HeightForWidthFunc;
/** /**
* *

Some files were not shown because too many files have changed in this diff Show More