1 #pragma once
2 #include "Geometry.h"
3 #include "Color.h"
4 #include <cairo/cairo.h>
5 #include <type_traits>
6 #include <memory>
7 #include <cmath>
8
9 cairo_surface_t *cairo_image_surface_create_from_png_data(const char *data, unsigned length);
10 void cairo_set_source_rgba8(cairo_t *cr, ColorRGBA8 c);
11
12 struct cairo_surface_deleter;
13 typedef std::unique_ptr<std::remove_pointer<cairo_surface_t>::type, cairo_surface_deleter> cairo_surface_u;
14
15 ///
16 struct cairo_surface_deleter {
operatorcairo_surface_deleter17 void operator()(cairo_surface_t *x) const noexcept { cairo_surface_destroy(x); }
18 };
19
20 template <class T>
cairo_rectangle(cairo_t * cr,const RectT<T> & r)21 inline void cairo_rectangle(cairo_t *cr, const RectT<T> &r)
22 {
23 cairo_rectangle(cr, r.x, r.y, r.w, r.h);
24 }
25
26 template <class T>
cairo_rounded_rectangle(cairo_t * cr,const RectT<T> & r,double radius)27 void cairo_rounded_rectangle(cairo_t *cr, const RectT<T> &r, double radius)
28 {
29 double degrees = M_PI / 180.0;
30
31 double x = r.x;
32 double y = r.y;
33 double w = r.w;
34 double h = r.h;
35
36 cairo_new_path(cr);
37 cairo_arc(cr, x + w - radius, y + radius, radius, -90 * degrees, 0 * degrees);
38 cairo_arc(cr, x + w - radius, y + h - radius, radius, 0 * degrees, 90 * degrees);
39 cairo_arc(cr, x + radius, y + h - radius, radius, 90 * degrees, 180 * degrees);
40 cairo_arc(cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
41 cairo_close_path(cr);
42 }
43
44 enum RectangleCorner {
45 RectangleNE = 1 << 0,
46 RectangleSE = 1 << 1,
47 RectangleSW = 1 << 2,
48 RectangleNW = 1 << 3,
49 RectangleAllCorners = RectangleNE|RectangleSE|RectangleSW|RectangleNW,
50 };
51
52 template <class T>
cairo_rounded_rectangle_with_corners(cairo_t * cr,const RectT<T> & r,double radius,int corners)53 void cairo_rounded_rectangle_with_corners(cairo_t *cr, const RectT<T> &r, double radius, int corners)
54 {
55 double degrees = M_PI / 180.0;
56
57 double x = r.x;
58 double y = r.y;
59 double w = r.w;
60 double h = r.h;
61
62 cairo_new_path(cr);
63 if (corners & RectangleNE)
64 cairo_arc(cr, x + w - radius, y + radius, radius, -90 * degrees, 0 * degrees);
65 else
66 cairo_move_to(cr, x + w, y);
67 if (corners & RectangleSE)
68 cairo_arc(cr, x + w - radius, y + h - radius, radius, 0 * degrees, 90 * degrees);
69 else
70 cairo_line_to(cr, x + w, y + h);
71 if (corners & RectangleSW)
72 cairo_arc(cr, x + radius, y + h - radius, radius, 90 * degrees, 180 * degrees);
73 else
74 cairo_line_to(cr, x, y + h);
75 if (corners & RectangleNW)
76 cairo_arc(cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
77 else
78 cairo_line_to(cr, x, y);
79 cairo_close_path(cr);
80 }
81