p1788 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 */