4 flatland is a simple 2d physical simulator
6 Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
7 Written by Francois Fleuret <francois.fleuret@idiap.ch>
9 This file is part of flatland
11 flatland is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License version 3 as
13 published by the Free Software Foundation.
15 flatland is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with flatland. If not, see <http://www.gnu.org/licenses/>.
25 #include "canvas_cairo.h"
29 #define MAX(x, y) ((x >= y) ? (x) : (y))
31 CanvasCairo::CanvasCairo(scalar_t scale, int nb_rows, int nb_cols, CanvasCairo **ca) {
35 for(int i = 0; i < nb_rows; i++) {
36 int row_height = 0, row_width = 0;
37 for(int j = 0; j < nb_cols; j++) {
38 CanvasCairo *this_ca = ca[i * nb_cols + j];
39 row_height = MAX(row_height, this_ca->_actual_height);
40 row_width += this_ca->_actual_width;
42 _actual_width = MAX(_actual_width, row_width);
43 _actual_height += row_height;
46 _data = new unsigned char [_actual_width * _actual_height * _depth];
49 for(int i = 0; i < nb_rows; i++) {
52 for(int j = 0; j < nb_cols; j++) {
53 CanvasCairo *this_ca = ca[i * nb_cols + j];
54 for(int y = 0; y < this_ca->_actual_height; y++) {
55 for(int x = 0; x < this_ca->_actual_width; x++) {
56 for(int d = 0; d < _depth; d++) {
57 _data[(x0 + x + _actual_width * (y0 + y))* _depth + d] =
58 this_ca->_data[(x + this_ca->_actual_width * y)* _depth + d];
63 row_height = MAX(row_height, this_ca->_actual_height);
64 x0 += this_ca->_actual_width;
69 _image = cairo_image_surface_create_for_data(_data,
73 _actual_width * _depth);
75 _context_resource = cairo_create(_image);
77 cairo_scale(_context_resource, scale, scale);
80 // cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
81 // cairo_set_line_width (_context_resource, 1.0);
84 CanvasCairo::CanvasCairo(scalar_t scale, int width, int height) {
85 _actual_width = int(width * scale);
86 _actual_height = int(height * scale);
89 _data = new unsigned char [_actual_width * _actual_height * _depth];
91 _image = cairo_image_surface_create_for_data(_data,
95 _actual_width * _depth);
97 _context_resource = cairo_create(_image);
99 cairo_scale(_context_resource, scale, scale);
101 cairo_set_line_width (_context_resource, 1.0);
104 // cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
105 // cairo_rectangle(_context_resource, 0, 0, width, height);
106 // cairo_fill(_context_resource);
109 CanvasCairo::~CanvasCairo() {
110 cairo_destroy(_context_resource);
111 cairo_surface_destroy(_image);
115 void CanvasCairo::clear() {
116 cairo_set_source_rgb(_context_resource, 1.0, 1.0, 1.0);
117 cairo_rectangle(_context_resource, 0, 0, _actual_width / _scale, _actual_height / _scale);
118 cairo_fill(_context_resource);
121 void CanvasCairo::set_line_width(scalar_t w) {
122 cairo_set_line_width (_context_resource, w);
125 void CanvasCairo::set_drawing_color(scalar_t r, scalar_t g, scalar_t b) {
126 cairo_set_source_rgb(_context_resource, r, g, b);
129 void CanvasCairo::draw_polygon(int filled, int nb, scalar_t *x, scalar_t *y) {
130 cairo_move_to(_context_resource, x[0], y[0]);
131 for(int n = 0; n < nb; n++) {
132 cairo_line_to(_context_resource, x[n], y[n]);
134 cairo_close_path(_context_resource);
137 cairo_stroke_preserve(_context_resource);
138 cairo_fill(_context_resource);
140 cairo_stroke(_context_resource);
144 static cairo_status_t write_cairo_to_file(void *closure,
145 const unsigned char *data,
146 unsigned int length) {
147 fwrite(data, 1, length, (FILE *) closure);
148 return CAIRO_STATUS_SUCCESS;
151 void CanvasCairo::write_png(FILE *file) {
152 cairo_surface_write_to_png_stream(_image, write_cairo_to_file, file);