+#include <cmath>
+
+#define MAX(x, y) ((x >= y) ? (x) : (y))
+
+CanvasCairo::CanvasCairo(scalar_t scale, int nb_rows, int nb_cols, CanvasCairo **ca) {
+ _actual_width = 0;
+ _actual_height = 0;
+
+ for(int i = 0; i < nb_rows; i++) {
+ int row_height = 0, row_width = 0;
+ for(int j = 0; j < nb_cols; j++) {
+ CanvasCairo *this_ca = ca[i * nb_cols + j];
+ row_height = MAX(row_height, this_ca->_actual_height);
+ row_width += this_ca->_actual_width;
+ }
+ _actual_width = MAX(_actual_width, row_width);
+ _actual_height += row_height;
+ }
+
+ _data = new unsigned char [_actual_width * _actual_height * _depth];
+
+ int x0, y0 = 0;
+ for(int i = 0; i < nb_rows; i++) {
+ x0 = 0;
+ int row_height = 0;
+ for(int j = 0; j < nb_cols; j++) {
+ CanvasCairo *this_ca = ca[i * nb_cols + j];
+ for(int y = 0; y < this_ca->_actual_height; y++) {
+ for(int x = 0; x < this_ca->_actual_width; x++) {
+ for(int d = 0; d < _depth; d++) {
+ _data[(x0 + x + _actual_width * (y0 + y))* _depth + d] =
+ this_ca->_data[(x + this_ca->_actual_width * y)* _depth + d];
+
+ }
+ }
+ }
+ row_height = MAX(row_height, this_ca->_actual_height);
+ x0 += this_ca->_actual_width;
+ }
+ y0 += row_height;
+ }
+
+ _image = cairo_image_surface_create_for_data(_data,
+ CAIRO_FORMAT_RGB24,
+ _actual_width,
+ _actual_height,
+ _actual_width * _depth);
+
+ _context_resource = cairo_create(_image);
+
+ cairo_scale(_context_resource, scale, scale);
+
+ clear();
+ // cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
+ // cairo_set_line_width (_context_resource, 1.0);
+}
+