Many fixes, now generates a single image per frame.
[dyncnn.git] / canvas_cairo.cc
index ec26f60..aeb7b9f 100644 (file)
 
 #include "canvas_cairo.h"
 
+#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);
+}
+
 CanvasCairo::CanvasCairo(scalar_t scale, int width, int height) {
-  const int actual_width = int(width * scale);
-  const int actual_height = int(height * scale);
-  const int depth = 4;
+  _actual_width = int(width * scale);
+  _actual_height = int(height * scale);
+  _scale = scale;
 
-  _data = new unsigned char [actual_width * actual_height * depth];
+  _data = new unsigned char [_actual_width * _actual_height * _depth];
 
   _image = cairo_image_surface_create_for_data(_data,
                                                CAIRO_FORMAT_RGB24,
-                                               actual_width,
-                                               actual_height,
-                                               actual_width * depth);
+                                               _actual_width,
+                                               _actual_height,
+                                               _actual_width * _depth);
 
   _context_resource = cairo_create(_image);
 
   cairo_scale(_context_resource, scale, scale);
 
-  cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
   cairo_set_line_width (_context_resource, 1.0);
 
-  cairo_rectangle(_context_resource, 0, 0, width, height);
-
-  cairo_fill(_context_resource);
+  clear();
+  // cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
+  // cairo_rectangle(_context_resource, 0, 0, width, height);
+  // cairo_fill(_context_resource);
 }
 
 CanvasCairo::~CanvasCairo() {
@@ -55,6 +112,11 @@ CanvasCairo::~CanvasCairo() {
   delete[] _data;
 }
 
+void CanvasCairo::clear() {
+  cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
+  cairo_rectangle(_context_resource, 0, 0, _actual_width / _scale, _actual_height / _scale);
+  cairo_fill(_context_resource);
+}
 
 void CanvasCairo::set_line_width(scalar_t w) {
   cairo_set_line_width (_context_resource, w);