Browse Source

Gmt module: Make ObjectGMTLayer class via ObjectGMTClass template. Add function GMT_LayerShift.

ObjPtr
Michael Uleysky 9 years ago
parent
commit
4df0d70633
  1. 1
      modules/gmt/modgmt.cpp
  2. 54
      modules/gmt/modgmt_func.cpp
  3. 7
      modules/gmt/modgmt_func.h
  4. 24
      modules/gmt/modgmt_objects.cpp
  5. 84
      modules/gmt/modgmt_objects.h
  6. 13
      modules/gmt/modgmt_structs.h

1
modules/gmt/modgmt.cpp

@ -40,5 +40,6 @@ int gmt_module_init(void* p)
RegisterFunction("ColorCMYK",GMT_ColorCMYK);
RegisterFunction("Pen",GMT_Type<struct gmt_pen>);
RegisterFunction("Font",GMT_Type<struct gmt_font>);
RegisterFunction("Shift",GMT_LayerShift);
return 0;
}

54
modules/gmt/modgmt_func.cpp

@ -77,3 +77,57 @@ ObjectBase* GMT_ColorCMYK(const ObjectList* input)
if(suc) return new ObjectGMTColor(c);
else return 0;
}
// Shifting layer
/*
Input:
1) Three arguments, first is Layer, second and third are double. Interprets as new absolute position in cm.
2) Pairs list. Names are l (layer), x, y, xrel (xr), yrel (yr). Pair with name l may be absent, in this case search in list and using as layer object with ObjectGMTLayer type. x and y are absolute positions in cm, xrel and yrel are shift from current position. x (y) and xrel (yrel) are mutually exlusive, but x (y) and yrel (xrel) can be used simultaneously. If position for some axis is absent, then this position is unchanged.
*/
ObjectBase* GMT_LayerShift(const ObjectList* input)
{
auto size=input->Size();
struct gmt_layer layer;
// Case 1
if(3==size)
{
Base2Layer l(input,0);
Base2Double x(input,1), y(input,2);
bool suc=true;
layer=l(&suc);
if(!suc) goto case2;
layer.shiftx=x(&suc);
layer.shifty=y(&suc);
if(!suc) goto case2;
return new ObjectGMTLayer(layer);
}
case2:
// Search layer for shifting
{
SearchParameter<struct gmt_layer> original(input,"layer","l");
bool suc=true;
layer=original(&suc);
if(!suc) goto fail; // Conversion failed or too many arguments
}
// Do shift
{
BaseM2Double xr(input,"xrel","xr"), yr(input,"yrel","yr");
Base2Double x(input,"x"), y(input,"y");
bool suc=true;
// Check duplicate parameters
if( ( x.Exist() && xr.Exist() ) || ( y.Exist() && yr.Exist() ) ) goto fail;
if(x.Exist()) layer.shiftx=x(&suc);
if(y.Exist()) layer.shifty=y(&suc);
if(xr.Exist()) layer.shiftx+=x(&suc);
if(yr.Exist()) layer.shifty+=y(&suc);
if(!suc) goto fail;
}
return new ObjectGMTLayer(layer);
fail:
return 0;
}

7
modules/gmt/modgmt_func.h

@ -9,6 +9,7 @@ ObjectBase* GMT_ColorGray(const ObjectList* input);
ObjectBase* GMT_ColorRGB(const ObjectList* input);
ObjectBase* GMT_ColorHSV(const ObjectList* input);
ObjectBase* GMT_ColorCMYK(const ObjectList* input);
ObjectBase* GMT_LayerShift(const ObjectList* input);
// Extension of OBTypeM template for easy work with lists
template<template<typename> class Func, class... O>
@ -260,6 +261,9 @@ typedef TypeStorage<struct gmt_pen>::Base2Type Base2Pen;
// Definitions for ObjectGMTFont
template<> class TypeStorage<struct gmt_font>: public gTypeStorage<struct gmt_font,ObjectList,ObjectString,ObjectReal,ObjectInt,ObjectGMTFont> {};
typedef TypeStorage<struct gmt_font>::Base2Type Base2Font;
// Definitions for ObjectGMTLayer
template<> class TypeStorage<struct gmt_layer>: public gTypeStorage<struct gmt_layer,ObjectList,ObjectGMTLayer> {};
typedef TypeStorage<struct gmt_layer>::Base2Type Base2Layer;
// Conversion from List to GMTRegion
/*
@ -1336,4 +1340,7 @@ ObjectBase* GMT_Type(const ObjectList* input)
else return 0;
}
// Shift position of layer
ObjectBase* GMT_LayerShift(const ObjectList* input);
#endif

24
modules/gmt/modgmt_objects.cpp

@ -7,6 +7,30 @@ template<> const std::string ObjectGMTColor::type="GMTColor";
template<> const std::string ObjectGMTDash::type="GMTDash";
template<> const std::string ObjectGMTPen::type="GMTPen";
template<> const std::string ObjectGMTFont::type="GMTFont";
template<> const std::string ObjectGMTLayer::type="GMTLayer";
template<> const int8_t* ObjectGMTLayer::Blob(size_t* size) const
{
if(s.Shifted())
{
std::string b="V "+ToString(cm2GMT(s.shiftx))+" "+ToString(cm2GMT(s.shifty))+" T\n";
std::string e="U\n";
int8_t* p=new int8_t[b.size()+s.data->size()+e.size()];
memcpy(p,b.data(),b.size());
memcpy(p+b.size(),s.data->data(),s.data->size());
memcpy(p+b.size()+s.data->size(),e.data(),e.size());
return p;
}
else
{
*size=s.data->size();
return reinterpret_cast<const int8_t*>(s.data->data());
}
}
template<> void ObjectGMTLayer::DeallocBlob(const int8_t* ptr) const
{
if(s.Shifted()) delete[] ptr;
}
std::map<std::string,gmt_projection::projection> gmt_projection::projnames;

84
modules/gmt/modgmt_objects.h

@ -35,6 +35,8 @@ class ObjectGMTClass: public ObjectBase
return true;
}
std::string Type() const override {return type;}
const int8_t* Blob(size_t* size) const override { *size=0; return 0; }
void DeallocBlob(const int8_t* ptr) const override {};
// Own functions
ObjectBase* Get(const std::string& gname) const
@ -129,77 +131,17 @@ template<> inline ObjectBase* ObjectGMTFont::OGet(const std::string& name) const
}
// GMTLayer
class ObjectGMTLayer: public ObjectBase
{
double shiftx,shifty;
struct gmt_projection proj;
std::string creator;
std::shared_ptr<std::string> data;
ObjectGMTLayer() {}
// This is saveable object
virtual const int8_t* Blob(size_t* size) const override
{
if(Shifted())
{
std::string b="V "+ToString(cm2GMT(shiftx))+" "+ToString(cm2GMT(shifty))+" T\n";
std::string e="U\n";
int8_t* p=new int8_t[b.size()+data->size()+e.size()];
memcpy(p,b.data(),b.size());
memcpy(p+b.size(),data->data(),data->size());
memcpy(p+b.size()+data->size(),e.data(),e.size());
return p;
}
else
{
*size=data->size();
return reinterpret_cast<const int8_t*>(data->data());
}
}
virtual void DeallocBlob(const int8_t* ptr) const override
{
if(Shifted()) delete[] ptr;
};
public:
// Constructor
ObjectGMTLayer(const std::string& newdata, const struct gmt_projection& newproj, const std::string& newcreator, double newshiftx=0.0, double newshifty=0.0):shiftx(newshiftx),shifty(newshifty),proj(newproj),creator(newcreator)
{
std::string* pdata=new std::string(newdata.data(),newdata.length()); // To prevent COW
data.reset(pdata);
}
// Pure virtual overrides
ObjectBase* Copy() const override
{
auto ret=new ObjectGMTLayer;
ret->shiftx=shiftx; ret->shifty=shifty;
ret->proj=proj;
ret->creator=creator;
ret->data=data;
return ret;
}
bool Print() const override
{
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Made by: "<<creator<<std::endl;
COUT(NORMAL)<<"Size: "<<proj.rwidth<<"x"<<proj.rheight<<std::endl;
if(Shifted()) COUT(NORMAL)<<"Shifted by: "<<shiftx<<"x"<<shifty<<std::endl;
return true;
}
std::string Type() const override {return "GMTLayer";}
// Own functions
ObjectBase* Get(const std::string& gname) const
{
std::string name=gname;
tolower(name);
if("proj"==name || "projection"==name) return new ObjectGMTProjection(proj);
if("w"==name || "width"==name) return new ObjectReal(proj.rwidth);
if("h"==name || "height"==name) return new ObjectReal(proj.rheight);
if("shiftx"==name) return new ObjectReal(shiftx);
if("shifty"==name) return new ObjectReal(shifty);
typedef ObjectGMTClass<struct gmt_layer> ObjectGMTLayer;
template<> inline ObjectBase* ObjectGMTLayer::OGet(const std::string& name) const
{
if("proj"==name || "projection"==name) return new ObjectGMTProjection(s.proj);
if("w"==name || "width"==name) return new ObjectReal(s.proj.rwidth);
if("h"==name || "height"==name) return new ObjectReal(s.proj.rheight);
if("shiftx"==name) return new ObjectReal(s.shiftx);
if("shifty"==name) return new ObjectReal(s.shifty);
return 0;
}
bool Shifted() const {return shiftx!=0.0 || shifty!=0.0;}
};
template<> const int8_t* ObjectGMTLayer::Blob(size_t* size) const;
template<> void ObjectGMTLayer::DeallocBlob(const int8_t* ptr) const;
#endif

13
modules/gmt/modgmt_structs.h

@ -795,4 +795,17 @@ struct gmt_font: public gmt_struct
static bool FillFontNames();
};
// Layer
struct gmt_layer: public gmt_struct
{
double shiftx,shifty;
struct gmt_projection proj;
std::string creator;
std::shared_ptr<std::string> data;
std::string Value() const {return creator+(Shifted()?("("+ToString(shiftx)+"x"+ToString(shifty)+")"):"");}
bool Shifted() const {return shiftx!=0.0 || shifty!=0.0;}
};
#endif

Loading…
Cancel
Save