|
|
@ -6,8 +6,39 @@ |
|
|
|
#include "common.h" |
|
|
|
#include "common.h" |
|
|
|
#include "modgmt_colornames.h" |
|
|
|
#include "modgmt_colornames.h" |
|
|
|
|
|
|
|
|
|
|
|
// Helper classes for conversion of doubles from strings with varios checks
|
|
|
|
// Helper template for checking double numbers acquired from Source with some Policies.
|
|
|
|
|
|
|
|
// Main definition, never instantiated
|
|
|
|
|
|
|
|
template<class Source, class... Policies> |
|
|
|
|
|
|
|
class GetDouble; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Recursive definition
|
|
|
|
|
|
|
|
template<class Source, class Policy, class... Policies> |
|
|
|
|
|
|
|
class GetDouble<Source, Policy, Policies...>: public GetDouble<Source, Policies...> |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Policy p; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
GetDouble(GetDouble&&) = delete; |
|
|
|
|
|
|
|
GetDouble(GetDouble&) = delete; |
|
|
|
|
|
|
|
template<class... Args> |
|
|
|
|
|
|
|
GetDouble(Args... args):GetDouble<Source,Policies...>(args...) {}; |
|
|
|
|
|
|
|
double operator()(bool* suc) const {return p(GetDouble<Source,Policies...>::operator()(suc),suc);} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Bottom of recursion
|
|
|
|
|
|
|
|
template<class Source> |
|
|
|
|
|
|
|
class GetDouble<Source>: public Source |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
GetDouble(GetDouble&&) = delete; |
|
|
|
|
|
|
|
GetDouble(GetDouble&) = delete; |
|
|
|
|
|
|
|
GetDouble() = delete; |
|
|
|
|
|
|
|
template<class... Args> |
|
|
|
|
|
|
|
GetDouble(Args... args):Source(args...) {}; |
|
|
|
|
|
|
|
double operator()(bool* suc) const {return Source::operator()(suc);} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// We use rational representation of floating point number, because double type values not allowed as template parameter
|
|
|
|
// We use rational representation of floating point number, because double type values not allowed as template parameter
|
|
|
|
|
|
|
|
// Policy to check if value is greater or equal num/denum
|
|
|
|
template<int32_t num, uint32_t denum=1> |
|
|
|
template<int32_t num, uint32_t denum=1> |
|
|
|
class PMin |
|
|
|
class PMin |
|
|
|
{ |
|
|
|
{ |
|
|
@ -15,6 +46,7 @@ class PMin |
|
|
|
double operator()(double v, bool* suc) const {if(v<static_cast<double>(num)/denum) *suc=false; return v;} |
|
|
|
double operator()(double v, bool* suc) const {if(v<static_cast<double>(num)/denum) *suc=false; return v;} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Policy to check if value is lesser or equal num/denum
|
|
|
|
template<int32_t num, uint32_t denum=1> |
|
|
|
template<int32_t num, uint32_t denum=1> |
|
|
|
class PMax |
|
|
|
class PMax |
|
|
|
{ |
|
|
|
{ |
|
|
@ -22,13 +54,14 @@ class PMax |
|
|
|
double operator()(double v, bool* suc) const {if(v>static_cast<double>(num)/denum) *suc=false; return v;} |
|
|
|
double operator()(double v, bool* suc) const {if(v>static_cast<double>(num)/denum) *suc=false; return v;} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class PFromValue |
|
|
|
// Get double value from string or number
|
|
|
|
|
|
|
|
class SourceValue |
|
|
|
{ |
|
|
|
{ |
|
|
|
double d; |
|
|
|
double d; |
|
|
|
bool ok; |
|
|
|
bool ok; |
|
|
|
public: |
|
|
|
public: |
|
|
|
PFromValue(const std::string& s) {ok=str2double(s,&d);} |
|
|
|
SourceValue(const std::string& s) {ok=str2double(s,&d);} |
|
|
|
PFromValue(double s):d(s),ok(true) {} |
|
|
|
SourceValue(double s):d(s),ok(true) {} |
|
|
|
double operator()(bool* suc) const |
|
|
|
double operator()(bool* suc) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(!ok) *suc=false; |
|
|
|
if(!ok) *suc=false; |
|
|
@ -36,39 +69,19 @@ class PFromValue |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Main definition, never instantiated
|
|
|
|
// Helper types for colors
|
|
|
|
template<class... Policies> |
|
|
|
typedef GetDouble<SourceValue,PMin<0>,PMax<255> > Value2RGB; |
|
|
|
class GetDouble; |
|
|
|
typedef GetDouble<SourceValue,PMin<0>,PMax<360> > Value2Hue; |
|
|
|
|
|
|
|
typedef GetDouble<SourceValue,PMin<0>,PMax<1> > Value2SV; |
|
|
|
// Recursive definition
|
|
|
|
typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2CMYK; |
|
|
|
template<class Policy, class... Policies> |
|
|
|
typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2Transp; |
|
|
|
class GetDouble<Policy, Policies...>: public GetDouble<Policies...> |
|
|
|
// Helper type for pens and dashes
|
|
|
|
{ |
|
|
|
typedef GetDouble<SourceValue,PMin<0> > Value2Width; |
|
|
|
Policy p; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
GetDouble(GetDouble&&) = delete; |
|
|
|
|
|
|
|
GetDouble(GetDouble&) = delete; |
|
|
|
|
|
|
|
template<class... Args> |
|
|
|
|
|
|
|
GetDouble(Args... args):GetDouble<Policies...>(args...) {}; |
|
|
|
|
|
|
|
double operator()(bool* suc) const {return p(GetDouble<Policies...>::operator()(suc),suc);} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Special case for PFromString policy. This policy mast be last in policies list.
|
|
|
|
class gmt_struct {}; // Base type for all gmt structures
|
|
|
|
template<> |
|
|
|
|
|
|
|
class GetDouble<PFromValue> |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
PFromValue p; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
GetDouble(GetDouble&&) = delete; |
|
|
|
|
|
|
|
GetDouble(GetDouble&) = delete; |
|
|
|
|
|
|
|
GetDouble() = delete; |
|
|
|
|
|
|
|
GetDouble(const std::string& str):p(str) {}; |
|
|
|
|
|
|
|
GetDouble(double d):p(d) {}; |
|
|
|
|
|
|
|
double operator()(bool* suc) const {return p(suc);} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coordinate
|
|
|
|
// Coordinate
|
|
|
|
struct gmt_coord |
|
|
|
struct gmt_coord: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool isdeg; |
|
|
|
bool isdeg; |
|
|
|
union |
|
|
|
union |
|
|
@ -138,7 +151,7 @@ struct gmt_coord |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Region
|
|
|
|
// Region
|
|
|
|
struct gmt_region |
|
|
|
struct gmt_region: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
enum Type {NORMAL,BBOX,GLOBAL360,GLOBAL180}; |
|
|
|
enum Type {NORMAL,BBOX,GLOBAL360,GLOBAL180}; |
|
|
|
Type type; |
|
|
|
Type type; |
|
|
@ -190,7 +203,7 @@ struct gmt_region |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Projection
|
|
|
|
// Projection
|
|
|
|
struct gmt_projection |
|
|
|
struct gmt_projection: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
// OBLIQMERCATOR types
|
|
|
|
// OBLIQMERCATOR types
|
|
|
|
enum class OType {NOTDEF,A,B,C}; |
|
|
|
enum class OType {NOTDEF,A,B,C}; |
|
|
@ -280,17 +293,11 @@ struct gmt_projection |
|
|
|
static std::map<std::string,projection> projnames; |
|
|
|
static std::map<std::string,projection> projnames; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Helper types for colors
|
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PMax<255>,PFromValue> Value2RGB; |
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PMax<360>,PFromValue> Value2Hue; |
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PMax<1>,PFromValue> Value2SV; |
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PMax<100>,PFromValue> Value2CMYK; |
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PMax<100>,PFromValue> Value2Transp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Color
|
|
|
|
// Color
|
|
|
|
struct gmt_color |
|
|
|
struct gmt_color: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
enum ColorModel {RGB,GRAY,HSV,CMYK}; |
|
|
|
enum ColorModel {RGB,GRAY,HSV,CMYK}; |
|
|
|
ColorModel model; |
|
|
|
ColorModel model; |
|
|
|
union |
|
|
|
union |
|
|
@ -601,39 +608,40 @@ struct gmt_color |
|
|
|
#include "modgmt_colortransform.h" |
|
|
|
#include "modgmt_colortransform.h" |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Helper types for pens
|
|
|
|
|
|
|
|
typedef GetDouble<PMin<0>,PFromValue> Value2Width; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Dash
|
|
|
|
// Dash
|
|
|
|
struct gmt_dash |
|
|
|
struct gmt_dash: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::vector<double> dash; |
|
|
|
std::vector<double> dash; |
|
|
|
double shift; |
|
|
|
double shift; |
|
|
|
|
|
|
|
double width; |
|
|
|
|
|
|
|
bool wisrel; |
|
|
|
|
|
|
|
static const double default_width; |
|
|
|
std::string Value() const |
|
|
|
std::string Value() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::string ret; |
|
|
|
std::string ret; |
|
|
|
if(dash.empty()) return ret; |
|
|
|
if(dash.empty()) return ret; |
|
|
|
for(auto i:dash) ret+=std::to_string(i/10.0)+"_"; |
|
|
|
for(auto i:dash) ret+=std::to_string((wisrel?width:1.0)*i/10.0)+"_"; |
|
|
|
ret.back()=':'; |
|
|
|
ret.back()=':'; |
|
|
|
ret+=std::to_string(shift)+"c"; |
|
|
|
ret+=std::to_string(shift)+"c"; |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
operator bool() const {return !dash.empty();} |
|
|
|
operator bool() const {return !dash.empty();} |
|
|
|
void Clear() {dash.clear(); shift=0.0;} |
|
|
|
void Clear() {dash.clear(); shift=0.0; wisrel=false;} |
|
|
|
|
|
|
|
|
|
|
|
bool Convert(const std::string& in, const double& w) |
|
|
|
bool Convert(const std::string& in, double w=0.0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Clear(); |
|
|
|
Clear(); |
|
|
|
shift=0; |
|
|
|
shift=0; |
|
|
|
if(0==in.size()) return true; // No dash
|
|
|
|
if(0==in.size()) return true; // No dash
|
|
|
|
if(std::string::npos==in.find_first_not_of(".-")) // dot-dash form
|
|
|
|
if(std::string::npos==in.find_first_not_of(".-")) // dot-dash form
|
|
|
|
{ |
|
|
|
{ |
|
|
|
double width=(0==w)?1:w; |
|
|
|
width=(0==w)?default_width:w; |
|
|
|
|
|
|
|
wisrel=true; |
|
|
|
for(const auto& i:in) |
|
|
|
for(const auto& i:in) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if('.'==i) dash.push_back(width); // Dot
|
|
|
|
if('.'==i) dash.push_back(1); // Dot
|
|
|
|
else dash.push_back(8*width); // Dash
|
|
|
|
else dash.push_back(8); // Dash
|
|
|
|
dash.push_back(4*width); // Gap
|
|
|
|
dash.push_back(4); // Gap
|
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -665,11 +673,12 @@ struct gmt_dash |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Pen
|
|
|
|
// Pen
|
|
|
|
struct gmt_pen |
|
|
|
struct gmt_pen: public gmt_struct |
|
|
|
{ |
|
|
|
{ |
|
|
|
double width; |
|
|
|
double width; |
|
|
|
struct gmt_color color; |
|
|
|
struct gmt_color color; |
|
|
|
struct gmt_dash dash; |
|
|
|
struct gmt_dash dash; |
|
|
|
|
|
|
|
static const double default_width; |
|
|
|
std::string Value() const {return std::to_string(width/10.0)+"c,"+color.Value()+(dash?(","+dash.Value()):"");} |
|
|
|
std::string Value() const {return std::to_string(width/10.0)+"c,"+color.Value()+(dash?(","+dash.Value()):"");} |
|
|
|
|
|
|
|
|
|
|
|
// Interpret one numeric argument as width value
|
|
|
|
// Interpret one numeric argument as width value
|
|
|
@ -692,7 +701,7 @@ struct gmt_pen |
|
|
|
WordList wl=Split(str,",",true); |
|
|
|
WordList wl=Split(str,",",true); |
|
|
|
|
|
|
|
|
|
|
|
// Defaults
|
|
|
|
// Defaults
|
|
|
|
width=1; |
|
|
|
width=default_width; |
|
|
|
color.Convert(0); // Black
|
|
|
|
color.Convert(0); // Black
|
|
|
|
dash.Clear(); |
|
|
|
dash.Clear(); |
|
|
|
|
|
|
|
|
|
|
|