diff --git a/modules/gmt/modgmt_func.h b/modules/gmt/modgmt_func.h index 3aa92ac..f6701ba 100644 --- a/modules/gmt/modgmt_func.h +++ b/modules/gmt/modgmt_func.h @@ -173,6 +173,7 @@ using Base2String=Base2Struct; using Base2Coord =Base2Struct; using Base2Region=Base2Struct; using Base2Proj =Base2Struct; +using Base2Color =Base2Struct; // Simple aliases of convertors with default values using Base2StringD=Base2StructD; @@ -210,6 +211,44 @@ class Base2NonNeg: public Base2Double }; using Base2NonNegD=DefaultConverter; +// Convertors for double values which must be in some interval +template +class Base2InRange: public Base2Double +{ + public: + double Convert(const ObjectBase* ob, bool* res, std::string& err) + { + double t=Base2Double::Convert(ob,res,err); + if(res && (tMax) ) + { + *res=false; + err="Value mast be in the interval from "+ToString(Min)+" to "+ToString(Max); + } + return t; + } +}; +template +using Base2InRangeD=DefaultConverter >; + +// Definitions for colors +constexpr int32_t TransMax = 100; +constexpr int32_t RGBMax = 255; +constexpr int32_t HueMax = 360; +constexpr int32_t SVMax = 1; +constexpr int32_t CMYKMax = 100; + +using Base2Trans = Base2InRange <0,TransMax>; +using Base2RGB = Base2InRange <0,RGBMax >; +using Base2Hue = Base2InRange <0,HueMax >; +using Base2SV = Base2InRange <0,SVMax >; +using Base2CMYK = Base2InRange <0,CMYKMax >; + +using Base2TransD = Base2InRangeD<0,TransMax>; +using Base2RGBD = Base2InRangeD<0,RGBMax >; +using Base2HueD = Base2InRangeD<0,HueMax >; +using Base2SVD = Base2InRangeD<0,SVMax >; +using Base2CMYKD = Base2InRangeD<0,CMYKMax >; + // Conversion from List to GMTRegion /* Input: @@ -663,19 +702,6 @@ class Convert2Struct } }; -// Helper types -typedef SearchParameterWDefO,false,PMin<0>,PMax<255> > Base2RGB; -typedef SearchParameterWDefO,false,PMin<0>,PMax<360> > Base2Hue; -typedef SearchParameterWDefO,false,PMin<0>,PMax<1 > > Base2SV; -typedef SearchParameterWDefO,false,PMin<0>,PMax<100> > Base2CMYK; -typedef SearchParameterWDefO,false,PMin<0>,PMax<100> > Base2Transp; - -typedef SearchParameter,PMax<255> > BaseM2RGB; -typedef SearchParameter,PMax<360> > BaseM2Hue; -typedef SearchParameter,PMax<1 > > BaseM2SV; -typedef SearchParameter,PMax<100> > BaseM2CMYK; -typedef SearchParameter,PMax<100> > BaseM2Transp; - // Converting List to GMTColor /* Input: @@ -695,144 +721,119 @@ template<> class Convert2Struct { public: - struct gmt_color operator()(const ObjectList* input, bool* issuc) const + struct gmt_color operator()(const ObjectList* input, bool* issuc, std::string& err) const { - struct gmt_color c; - auto size=input->Size(); + struct gmt_color C; - if(1==size) // Cases 1, 2 and 4 + if(1==input->Size()) // Cases 1, 2 and 4 { - Base2Color color(input,0); + Base2Color color; bool suc=true; - c=color(&suc); + C=color.Convert(input->At(0),&suc,err); if(!suc) goto fail; // Conversion failed - return c; + return C; } // Case 3 { + ONFPar color("color"); + ONPar trans("transparency",0); + ONPar gray("gr(a|e)y"), r("red"), g("green"), b("blue"); + ONPar h("hue"); + ONPar s("saturation"), v("value"); + ONPar c("cyan"), m("magenta"), y("yellow"), k("[blac]k"); + + {ParseNamedParameters params(input,color,trans,gray,r,g,b,h,s,v,c,m,y,k); if(!params) {err=params.Error(); goto fail;} } // Fail to parse by variant 3 + bool cmodset=false; - bool upd; - { - BaseMT2Color updarg(input,"color"); - bool suc=true; - c=updarg(&upd,&suc); - if(upd && !suc) goto fail; // Conversion failed or too many arguments - } + bool upd=color.Exist(); + if(!upd) { // default color is black - c.transparency=0; - c.model=gmt_color::GRAY; - c.gray=0.0; + C.transparency=trans; + C.model=gmt_color::GRAY; + C.gray=0.0; } + else C=color; - { - BaseM2Transp t(input,"t","transp","transparency"); - if(t.Exist()) - { - bool suc=true; - c.transparency=t(&suc); - if(!suc) goto fail; // Parsing error - } - } + if(trans.Exist()) C.transparency=trans; // GRAY + if(gray.Exist()) { - BaseM2RGB g(input,"gray","grey"); - if(g.Exist()) - { - if(cmodset) goto fail; // Model already set - bool suc=true; - c.model=gmt_color::GRAY; - c.gray=g(&suc); // Update mode ignored in this case - if(!suc) goto fail; // Parsing error - cmodset=true; - } + if(cmodset) {err="Can't select between different color models"; goto fail;} // Model already set + C.model=gmt_color::GRAY; + C.gray=gray; // Update mode ignored in this case + cmodset=true; } // RGB + if(r.Exist() || g.Exist() || b.Exist()) { - BaseM2RGB r(input,"r","red"), g(input,"g","green"), b(input,"b","blue"); - if(r.Exist() || g.Exist() || b.Exist()) - { - if(cmodset) goto fail; // Model already set - bool suc=true; - c.ToRGB(); - if(r.Exist()) c.r=r(&suc); - if(g.Exist()) c.g=g(&suc); - if(b.Exist()) c.b=b(&suc); - if(!suc) goto fail; // Parsing error - cmodset=true; - } + if(cmodset) {err="Can't select between different color models"; goto fail;} // Model already set + C.ToRGB(); + if(r.Exist()) C.r=r; + if(g.Exist()) C.g=g; + if(b.Exist()) C.b=b; + cmodset=true; } // HSV + if(h.Exist() || s.Exist() || v.Exist()) { - BaseM2Hue h(input,"h","hue"); - BaseM2SV s(input,"s","sat","saturation"), v(input,"v","val","value"); - if(h.Exist() || s.Exist() || v.Exist()) - { - if(cmodset) goto fail; // Model already set - bool suc=true; - c.ToHSV(); - if(h.Exist()) c.hue=h(&suc); - if(s.Exist()) c.saturation=s(&suc); - if(v.Exist()) c.value=v(&suc); - if(!suc) goto fail; // Parsing error - cmodset=true; - } + if(cmodset) {err="Can't select between different color models"; goto fail;} // Model already set + C.ToHSV(); + if(h.Exist()) C.hue=h; + if(s.Exist()) C.saturation=s; + if(v.Exist()) C.value=v; + cmodset=true; } // CMYK + if(c.Exist() || m.Exist() || y.Exist() || k.Exist()) { - BaseM2CMYK cc(input,"c","cyan"), m(input,"m","magenta"), y(input,"y","yellow"), k(input,"k","black"); - if(cc.Exist() || m.Exist() || y.Exist() || k.Exist()) - { - if(cmodset) goto fail; // Model already set - bool suc=true; - c.ToCMYK(); - if(cc.Exist()) c.cyan=cc(&suc); - if(m.Exist()) c.magenta=m(&suc); - if(y.Exist()) c.yellow=y(&suc); - if(k.Exist()) c.black=k(&suc); - if(!suc) goto fail; // Parsing error - cmodset=true; - } + if(cmodset) {err="Can't select between different color models"; goto fail;} // Model already set + C.ToCMYK(); + if(c.Exist()) C.cyan=c; + if(m.Exist()) C.magenta=m; + if(y.Exist()) C.yellow=y; + if(k.Exist()) C.black=k; + cmodset=true; } - if(cmodset || upd) return c; // Color created or updated + + if(cmodset || upd) return C; // Color created or updated } // Case 5 - if(3==size) + if(3==input->Size()) { - Base2RGB r(input,0), g(input,1), b(input,2); - c.model=gmt_color::RGB; - bool suc=true; - c.r=r(&suc); - c.g=g(&suc); - c.b=b(&suc); - if(!suc) goto fail; // Parsing error - return c; + RPosPar r("red"), g("green"), b("blue"); + ParsePositionalParameters params(input,r,g,b); + + if(!params) {err=params.Error(); goto fail;} // Fail to parse by variant 5 + + C.model=gmt_color::RGB; + C.r=r; C.g=g; C.b=b; + return C; } // Case 6 - if(4==size) + if(4==input->Size()) { - Base2CMYK cc(input,0), m(input,1), y(input,2), k(input,3); - c.model=gmt_color::CMYK; - bool suc=true; - c.cyan=cc(&suc); - c.magenta=m(&suc); - c.yellow=y(&suc); - c.black=k(&suc); - if(!suc) goto fail; // Parsing error - return c; + RPosPar c("cyan"), m("magenta"), y("yellow"), k("black"); + ParsePositionalParameters params(input,c,m,y,k); + + if(!params) {err=params.Error(); goto fail;} // Fail to parse by variant 6 + C.model=gmt_color::CMYK; + C.cyan=c; C.magenta=m; C.yellow=y; C.black=k; + return C; } + err="Incorrect number of arguments"; fail: *issuc=false; - return c; // Something go wrong + return C; // Something go wrong } };