#ifndef ROTOR_NODES_DRAWING #define ROTOR_NODES_DRAWING #include "rotor.h" #include namespace Rotor { class Draw_node: public Image_node { public: Draw_node(){ create_image_input("image input","Image input"); //no title or description as it isn't intended for the user }; Draw_node(map &settings):Draw_node() { }; ~Draw_node(){}; Draw_node* clone(map &_settings) { return new Draw_node(_settings);}; virtual void vector_output(cairo_t * cr,const Frame_spec &frame){}; Image *output(const Frame_spec &frame){ Image *in=image_inputs[0]->get(frame); if (in){ image=(*in); } else image.clear(); //convert to 32 bit - this can probably be optimised further cv::Mat chans; cv::cvtColor(image.rgb, chans, CV_BGR2RGBA, 4); cairo_surface_t * cs = cairo_image_surface_create_for_data (chans.data, CAIRO_FORMAT_RGB24, image.w, image.h, image.w*4); cairo_t * cr = cairo_create (cs); //do any kind of vector drawing vector_output(cr,frame); //convert frame back to 24 bits cv::cvtColor(chans,image.rgb,CV_RGBA2BGR,3); cairo_destroy(cr); cairo_surface_destroy(cs); return ℑ } private: }; class Hello_draw: public Draw_node { public: Hello_draw(){ //no title or description as it isn't intended for the user }; Hello_draw(map &settings) { base_settings(settings); }; ~Hello_draw(){}; Hello_draw* clone(map &_settings) { return new Hello_draw(_settings);}; void vector_output(cairo_t * cr,const Frame_spec &frame){ cairo_text_extents_t te; cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_select_font_face (cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 50); cairo_text_extents(cr, "hello, world!", &te); cairo_move_to (cr,(frame.w-te.width)/2,(frame.h-te.height)/2); cairo_show_text (cr, "hello, world!"); cairo_fill(cr); } private: }; #define SHAPE_circle 1 #define SHAPE_square 2 #define SHAPE_triangle 3 class Shape: public Draw_node { public: Shape(){ title="Shape"; description="Draws filled shapes"; create_parameter("x","number","X coordinate","X",0.0f); create_parameter("y","number","Y coordinate","Y",0.0f); create_parameter("scale","number","Scale","Scale",1.0f); create_parameter("rotation","number","Rotation","Rotation",0.0f); create_attribute("colour","Colour to fill","Colour","FFFFFF"); create_attribute("shape","Shape to draw","Shape","square",{"circle","square","triangle"}); }; Shape(map &settings):Shape() { base_settings(settings); colour=Colour(attributes["colour"]->value); }; ~Shape(){}; Shape* clone(map &_settings) { return new Shape(_settings);}; void vector_output(cairo_t * cr,const Frame_spec &frame){ cairo_set_source_rgb(cr, colour.Rfloat(),colour.Gfloat(),colour.Bfloat()); cairo_save(cr); //not really even necessary? cairo_translate(cr, frame.w/2, frame.h/2); cairo_translate(cr, parameters["x"]->value * frame.w, parameters["y"]->value * frame.h); cairo_scale(cr, parameters["scale"]->value , parameters["scale"]->value ); cairo_rotate(cr,(parameters["rotation"]->value/180.0f)*M_PI); switch(attributes["shape"]->intVal) { case SHAPE_square: cairo_rectangle(cr,-frame.w/2,-frame.w/2,frame.w,frame.w); break; case SHAPE_circle: cairo_arc(cr,0,0,frame.w/2,0.0, 2 * M_PI); break; case SHAPE_triangle: //subtracting PI/2 =(1.5*PI)/3 so the triangle is pointing up cairo_line_to(cr,0,-frame.w/2); cairo_line_to(cr,cos((0.5 * M_PI)/3)*frame.w/2,sin((0.5 * M_PI)/3)*frame.w/2); cairo_line_to(cr,cos((2.5 * M_PI)/3)*frame.w/2,sin((2.5 * M_PI)/3)*frame.w/2); cairo_close_path(cr); break; } cairo_restore (cr); //not really even necessary? cairo_fill(cr); } private: Colour colour; }; } #endif