/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLCore/src/ICLCore/AbstractCanvas.h ** ** Module : ICLCore ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #pragma once #include #include #include #include #include #include namespace icl{ using namespace math; using namespace utils; namespace core{ class ICLCore_API AbstractCanvas : public utils::Uncopyable{ public: typedef math::FixedMatrix Transform; typedef core::Color4D32f Color; struct ICLCore_API ClipRect{ ClipRect(float minx=0, float maxx=0, float miny=0, float maxy=0): minx(minx),maxx(maxx),miny(miny),maxy(maxy){} float minx; float maxx; float miny; float maxy; bool in(float x, float y) const{ return ((x >= minx) && (x<= maxx) && (y >= miny) && (y <= maxy)); } bool in(const Point32f &p) const{ return in(p.x,p.y); } }; protected: struct State{ AbstractCanvas::Transform T; AbstractCanvas::Color linecolor; AbstractCanvas::Color fillcolor; float linewidth; float pointsize; float symsize; float fontsize; std::string fontname; ClipRect clip; inline State(): T(AbstractCanvas::Transform::id()), linecolor(255,0,0,255),fillcolor(0,0,0,0), linewidth(1),pointsize(1),symsize(10), fontsize(10),fontname("arial"){} }; State state; std::vector stack; inline utils::Point32f transform(float x, float y) const{ return Point32f(state.T(0,0)*x + state.T(1,0)*y + state.T(2,0), state.T(0,1)*x + state.T(1,1)*y + state.T(2,1)); } inline bool clip(float x, float y) const{ return state.clip.in(x,y); } inline bool clip(const Point32f &p) const{ return state.clip.in(p); } public: AbstractCanvas(){} virtual ~AbstractCanvas(){} virtual void draw_point_internal(const utils::Point32f &p) = 0; virtual void draw_line_internal(const utils::Point32f &a, const utils::Point32f &b) = 0; virtual void fill_triangle_internal(const utils::Point32f &a, const utils::Point32f &b, const utils::Point32f &c) = 0; virtual void draw_ellipse_internal(const utils::Point32f &c, const utils::Point32f &axis1, const utils::Point32f &axis2) = 0; virtual void draw_image_internal(const utils::Point32f &ul, const utils::Point32f &ur, const utils::Point32f &lr, const utils::Point32f &ll, float alpha, scalemode sm) = 0; public: virtual const Transform &getTransform() const{ return state.T; } virtual void getTransform(float &angle, float &tx, float &ty) const{ angle = acos(state.T(0,0)); tx = state.T(2,0); ty = state.T(2,1); } virtual Rect32f getClipRect(){ return Rect32f(state.clip.minx, state.clip.miny, state.clip.maxx-state.clip.minx, state.clip.maxy-state.clip.miny); } virtual void push(){ stack.push_back(state); } virtual void pop() throw (utils::ICLException){ ICLASSERT_THROW(stack.size(), utils::ICLException("AbstractCanvas::pop: stack is empty")); state = stack.back(); stack.pop_back(); } virtual void point(float x, float y); virtual void line(float x0, float y0, float x1, float y1); virtual void triangle(float x0, float y0, float x1, float y1, float x2, float y2); virtual void sym(char c, float x, float y) throw (utils::ICLException); virtual void linestrip(int n, const float *xs, const float *ys, int xStride=1, int yStride=1, bool loop=false); virtual void rect(float x, float y, float w, float h); virtual void circle(float cx, float cy, float r); virtual void ellipse(float cx, float cy, float rx, float ry); virtual void image(const ImgBase *image, float xanchor, float yanchor, float alpha, scalemode sm=interpolateLIN, bool centered=false) throw (utils::ICLException); virtual void text(const std::string &t, float x, float y, bool centered = false); virtual void linecolor(float r, float g, float b, float a=255){ state.linecolor = Color(r,g,b,a); } virtual void fillcolor(float r, float g, float b, float a=255){ state.fillcolor = Color(r,g,b,a); } virtual void linewidth(float width){ state.linewidth = width; } virtual void pointsize(float size){ state.pointsize = size; } virtual void symsize(float size){ state.symsize = size; } virtual void fontsize(float size){ state.fontsize = size; } virtual void fontname(const std::string &fontname){ state.fontname = fontname; } virtual void transform(const Transform &T){ state.T = T*state.T; } virtual void transform(float tx, float ty, float angle){ if(angle){ const float sa = sin(angle), ca = cos(angle); state.T = Transform(ca,sa,tx, -sa,ca,ty, 0,0,1)*state.T; }else{ state.T(2,0) += tx; state.T(2,1) += ty; } } /// resets the transform virtual void reset(){ state.T = Transform::id(); } virtual void rotate(float angle){ transform(0,0,angle); } virtual void translate(float tx, float ty){ transform(tx,ty,0); } virtual void scale(float s){ scale(s,s); } virtual void scale(float sx, float sy){ state.T = Transform(sx,0,0, 0,sy,0, 0,0,1) * state.T; } }; } }