p1788 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,294 @@
1
+ /* Copyright (C) 2022 Théotime Bollengier <theotime.bollengier@ensta-bretagne.fr>
2
+ *
3
+ * This file is part of P1788. <https://gitlab.ensta-bretagne.fr/bollenth/p1788>
4
+ *
5
+ * P1788 is free software: you can redistribute it and/or modify it
6
+ * under the terms of the GNU General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License,
8
+ * or (at your option) any later version.
9
+ *
10
+ * P1788 is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ * See the GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with P1788. If not, see <https://www.gnu.org/licenses/>. 
17
+ */
18
+
19
+ #ifndef P1788_FIGURE_HH
20
+ #define P1788_FIGURE_HH
21
+
22
+ #include <string>
23
+ #include <vector>
24
+ #include <cairo/cairo.h>
25
+ #include <p1788/p1788.hpp>
26
+
27
+ using Interval = p1788::infsup::interval<double, p1788::flavor::infsup::setbased::mpfr_bin_ieee754_flavor>;
28
+ using IntervalVector = std::vector<Interval>;
29
+ //typedef p1788::infsup::interval<double, p1788::flavor::infsup::setbased::mpfr_bin_ieee754_flavor> Interval;
30
+ //typedef std::vector<Interval> IntervalVector ;
31
+
32
+ #if 0
33
+ class Interval {
34
+ public:
35
+ double inf;
36
+ double sup;
37
+ Interval() : inf(1), sup(-1) {}
38
+ Interval(double lb, double ub) : inf(lb), sup(ub) {}
39
+ bool is_empty() const { return (inf > sup); }
40
+ bool is_common() const { return true; }
41
+ double width() const { return (sup - inf); }
42
+ Interval operator&(const Interval& other) const {
43
+ if (is_empty() || other.is_empty() || sup < other.inf || inf > other.sup)
44
+ return Interval();
45
+ return Interval(std::max(inf, other.inf), std::min(sup, other.sup));
46
+ }
47
+ Interval operator+(const Interval& other) const {
48
+ return Interval(inf + other.inf, sup+other.sup);
49
+ }
50
+ Interval operator*(const Interval& other) const {
51
+ double a = inf*other.inf;
52
+ double b = inf*other.sup;
53
+ double c = sup*other.inf;
54
+ double d = sup*other.sup;
55
+ return Interval(
56
+ std::min(std::min(a, b), std::min(c, d)),
57
+ std::max(std::max(a, b), std::max(c, d)));
58
+ }
59
+ };
60
+ #endif
61
+
62
+
63
+ namespace P1788Figure {
64
+
65
+
66
+ class Box {
67
+ public:
68
+ Interval x;
69
+ Interval y;
70
+
71
+ Box() : x(), y() {}
72
+ Box(const Interval& ix, const Interval& iy) : x(ix), y(iy) {}
73
+ Box(const Box& b) : x(b.x), y(b.y) {}
74
+ Box& operator=(const Box& b) { x = b.x; y = b.y; return *this; }
75
+ Box& operator=(Box&& b) { x = std::move(b.x); y = std::move(b.y); return *this; }
76
+ Box operator&(const Box& other) const { return Box(Interval::intersection(x, other.x), Interval::intersection(y, other.y)); }
77
+ bool is_empty() const { return (Interval::is_empty(x) || Interval::is_empty(y)); }
78
+ };
79
+
80
+
81
+ class StringWithExtent {
82
+ public:
83
+ std::string str;
84
+ float width, height, x_bearing, y_bearing;
85
+ double value;
86
+ StringWithExtent() : str(), width(0.0f), height(0.0f), x_bearing(0.0f), y_bearing(0.0f), value(0.0) {}
87
+ StringWithExtent(const std::string& s) : str(s), width(0.0f), height(0.0f), x_bearing(0.0f), y_bearing(0.0f), value(0.0) {}
88
+ StringWithExtent(std::string&& s) : str(std::move(s)), width(0.0f), height(0.0f), x_bearing(0.0f), y_bearing(0.0f), value(0.0) {}
89
+ StringWithExtent(StringWithExtent&& s) :
90
+ str(std::move(s.str)), width(s.width), height(s.height), x_bearing(s.x_bearing), y_bearing(s.y_bearing), value(s.value) {}
91
+ bool empty() const { return str.empty(); }
92
+ };
93
+
94
+
95
+ class TickAxis {
96
+ private:
97
+ Interval m_interval;
98
+ double m_nice_min;
99
+ double m_nice_max;
100
+ double m_tick_spacing;
101
+ int m_nb_ticks;
102
+
103
+ void update();
104
+
105
+ public:
106
+ TickAxis(const Interval& interval, int nb_ticks);
107
+ void set_min_max(const Interval& interval) { if (Interval::is_common_interval(interval)){m_interval = interval; update();} }
108
+ void set_min_max(double mi, double mx) { set_min_max(Interval(mi, mx)); }
109
+ void set_nb_ticks(int n) { if (n >= 2){m_nb_ticks = n; update();} }
110
+ double min() const { return Interval::inf(m_interval); }
111
+ double max() const { return Interval::sup(m_interval); }
112
+ double nice_min() const { return m_nice_min; }
113
+ double nice_max() const { return m_nice_max; }
114
+ int nb_ticks() const { return m_nb_ticks; }
115
+ double tick_spacing() const { return m_tick_spacing; }
116
+ std::vector<double> get_coordinates() const;
117
+ std::vector<StringWithExtent> get_coordinate_strings() const;
118
+ };
119
+
120
+
121
+ class Figure;
122
+
123
+
124
+ class State {
125
+ public:
126
+ cairo_t *cr; // cairo context
127
+ Figure *figure;
128
+ unsigned int width, height;
129
+ double m_Sx, m_Sy, m_Tx, m_Ty;
130
+ bool stroke;
131
+ float stroke_width;
132
+ unsigned int stroke_color;
133
+ bool fill;
134
+ unsigned int fill_color;
135
+ Box frame_box;
136
+ int figwidth, figheight;
137
+ int top_offset, bot_offset, left_offset, right_offset;
138
+ TickAxis *xtickaxis, *ytickaxis;
139
+ std::vector<StringWithExtent> x_grad, y_grad;
140
+ StringWithExtent xlabel, ylabel, title;
141
+ float max_x_grad_height, max_y_grad_width, char_height, char_width;
142
+
143
+ State(Figure* figure);
144
+ ~State();
145
+ void decorate();
146
+ void real_box_to_screen_box(const Box& rb, Box& sb) const;
147
+ void set_source_color(unsigned int c);
148
+
149
+ private:
150
+ void calculate_spacings();
151
+ void set_font_options(cairo_t*);
152
+ };
153
+
154
+
155
+ class Command {
156
+ public:
157
+ typedef enum {
158
+ NONE = 0x00,
159
+ STROKE = 0x01,
160
+ FILL = 0x02,
161
+ STROKE_WIDTH = 0x04,
162
+ STROKE_COLOR = 0x08,
163
+ FILL_COLOR = 0x10,
164
+ DRAW_BOXES = 0x20
165
+ } command_type_t;
166
+ private:
167
+ command_type_t m_type;
168
+ union {
169
+ bool m_bool;
170
+ float m_float;
171
+ unsigned int m_uint;
172
+ std::vector<Box> m_boxes;
173
+ };
174
+ public:
175
+ // Command();
176
+ Command(command_type_t, bool);
177
+ Command(command_type_t, float);
178
+ Command(command_type_t, unsigned int);
179
+ Command(command_type_t, std::vector<Box>&&);
180
+ Command(command_type_t, const Box&);
181
+ Command(Command&&);
182
+ ~Command();
183
+ void exec(State& s);
184
+ command_type_t type() const { return m_type; }
185
+ bool is_a_draw_box_command() const { return (m_type == DRAW_BOXES); }
186
+ const std::vector<Box>& boxes() const { return m_boxes; }
187
+ void push_box(const Box&);
188
+ size_t allocated_size() const;
189
+ };
190
+
191
+
192
+ class Figure {
193
+ private:
194
+ unsigned int m_width;
195
+ unsigned int m_height;
196
+ Interval m_xlim;
197
+ Interval m_ylim;
198
+ std::string m_xlabel;
199
+ std::string m_ylabel;
200
+ std::string m_title;
201
+ bool m_bold_title;
202
+ bool m_do_print_graduation;
203
+ std::string m_graduation_font;
204
+ float m_graduation_font_size;
205
+ unsigned int m_graduation_color;
206
+ float m_graduation_stroke_width;
207
+ float m_label_font_size;
208
+ float m_title_font_size;
209
+ bool m_do_stroke;
210
+ unsigned int m_stroke_color;
211
+ float m_stroke_width;
212
+ bool m_do_fill;
213
+ unsigned int m_fill_color;
214
+ unsigned int m_background_color;
215
+ std::vector<Command> m_commands;
216
+
217
+ public:
218
+ Figure();
219
+ // ~Figure();
220
+
221
+ void cmd_stroke(bool);
222
+ void cmd_stroke_color(unsigned int);
223
+ void cmd_stroke_width(float);
224
+ void cmd_fill(bool);
225
+ void cmd_fill_color(unsigned int);
226
+ void cmd_draw_box(const IntervalVector&);
227
+ void cmd_draw_boxes(const std::vector<IntervalVector*>&);
228
+ void cmd_draw_boxes(std::vector<Box>&&);
229
+
230
+ void set_title(const std::string&);
231
+ void set_title_bold(bool);
232
+ void set_background_color(unsigned int c);
233
+ void set_width(int width);
234
+ void set_height(int height);
235
+ void set_xlabel(const std::string& l);
236
+ void set_ylabel(const std::string& l);
237
+ void set_xlimit(const Interval& l);
238
+ void set_ylimit(const Interval& l);
239
+ void set_print_graduations(bool b);
240
+ void set_graduation_font(const std::string& s);
241
+ void set_graduation_font_size(float s);
242
+ void set_graduation_color(unsigned int);
243
+ void set_graduation_stroke_width(float s);
244
+ void set_label_font_size(float s);
245
+ void set_title_font_size(float s);
246
+ void reset();
247
+
248
+ bool do_stroke() const { return m_do_stroke; }
249
+ double stroke_width() const { return (double)m_stroke_width; }
250
+ unsigned int stroke_color() const { return m_stroke_color; }
251
+ unsigned int fill_color() const { return m_fill_color; }
252
+ bool do_fill() const { return m_do_fill; }
253
+ bool print_graduations() const { return m_do_print_graduation; }
254
+ bool title_bold() const { return m_bold_title; }
255
+ unsigned int graduation_color() const { return m_graduation_color; }
256
+ unsigned int background_color() const { return m_background_color; }
257
+ double graduation_stroke_width() const { return (double)m_graduation_stroke_width; }
258
+ const Interval& xlim() const { return m_xlim; }
259
+ const Interval& ylim() const { return m_ylim; }
260
+ int width() const { return (int)m_width; };
261
+ int height() const { return (int)m_height; };
262
+ double graduation_font_size() const { return (double)m_graduation_font_size; }
263
+ double label_font_size() const;
264
+ double title_font_size() const;
265
+ double label_font_size_as_set() const { return (double)m_label_font_size; }
266
+ double title_font_size_as_set() const { return (double)m_title_font_size; }
267
+ const std::string& graduation_font() const { return m_graduation_font; }
268
+ const std::string& xlabel() const { return m_xlabel; }
269
+ const std::string& ylabel() const { return m_ylabel; }
270
+ const std::string& title() const { return m_title; }
271
+ void find_limits(Box& limits, Box& nice_limits) const;
272
+ void find_unbounded_limits(Box& limits) const;
273
+ size_t allocated_size() const;
274
+
275
+ #ifdef CAIRO_HAS_IMAGE_SURFACE
276
+ void write_png(const std::string& file_name);
277
+ std::string to_png();
278
+ #endif
279
+ #ifdef CAIRO_HAS_SVG_SURFACE
280
+ void write_svg(const std::string& file_name);
281
+ std::string to_svg();
282
+ #endif
283
+ #ifdef CAIRO_HAS_PDF_SURFACE
284
+ void write_pdf(const std::string& file_name);
285
+ std::string to_pdf();
286
+ #endif
287
+
288
+ private:
289
+ void exec_commands(State&);
290
+ }; // class Figure
291
+
292
+ } // namespace P1788
293
+
294
+ #endif /* P1788_FIGURE_HH */