summaryrefslogtreecommitdiff
path: root/rotord/src/nodes_drawing.h
blob: 91771f88b8f0d4f2e743532eba29ef7baa32e722 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#ifndef ROTOR_NODES_DRAWING
#define ROTOR_NODES_DRAWING

#include "rotor.h"
#include <cairo.h>

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<string,string> &settings):Draw_node() {
			};
			~Draw_node(){};
			Draw_node* clone(map<string,string> &_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 &image;
			}
		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<string,string> &settings) {
				base_settings(settings);
			};
			~Hello_draw(){};
			Hello_draw* clone(map<string,string> &_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<string,string> &settings):Shape() {
				base_settings(settings);
				colour=Colour(attributes["colour"]->value);
			};
			~Shape(){};
			Shape* clone(map<string,string> &_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