1 /* The Unico Theming Engine for Gtk+.
2 * Copyright (C) 2011 Canonical Ltd
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License
6 * version 2.1 as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free
15 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 *
18 * Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
19 *
20 */
21
22 #include <cairo.h>
23 #include <gtk/gtk.h>
24
25 #include "unico-cairo-support.h"
26 #include "unico-support.h"
27 #include "unico-types.h"
28
29 void
unico_cairo_round_rect(cairo_t * cr,gdouble x,gdouble y,gdouble width,gdouble height,gint radius,guint sides,GtkJunctionSides junction)30 unico_cairo_round_rect (cairo_t *cr,
31 gdouble x,
32 gdouble y,
33 gdouble width,
34 gdouble height,
35 gint radius,
36 guint sides,
37 GtkJunctionSides junction)
38 {
39 radius = CLAMP (radius, 0, MIN (width / 2, height / 2));
40
41 if (sides & SIDE_RIGHT)
42 {
43 if (radius == 0 ||
44 (junction & GTK_JUNCTION_CORNER_TOPRIGHT))
45 cairo_move_to (cr, x + width, y);
46 else
47 {
48 cairo_new_sub_path (cr);
49
50 cairo_arc (cr, x + width - radius, y + radius, radius, - G_PI / 4, 0);
51 }
52
53 if (radius == 0 ||
54 (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT))
55 cairo_line_to (cr, x + width, y + height);
56 else
57 cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI / 4);
58 }
59
60 if (sides & SIDE_BOTTOM)
61 {
62 if (radius != 0 &&
63 ! (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT))
64 {
65 if ((sides & SIDE_RIGHT) == 0)
66 cairo_new_sub_path (cr);
67
68 cairo_arc (cr, x + width - radius, y + height - radius, radius, G_PI / 4, G_PI / 2);
69 }
70 else if ((sides & SIDE_RIGHT) == 0)
71 cairo_move_to (cr, x + width, y + height);
72
73 if (radius == 0 ||
74 (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT))
75 cairo_line_to (cr, x, y + height);
76 else
77 cairo_arc (cr, x + radius, y + height - radius, radius, G_PI / 2, 3 * (G_PI / 4));
78 }
79 else
80 cairo_move_to (cr, x, y + height);
81
82 if (sides & SIDE_LEFT)
83 {
84 if (radius != 0 &&
85 ! (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT))
86 {
87 if ((sides & SIDE_BOTTOM) == 0)
88 cairo_new_sub_path (cr);
89
90 cairo_arc (cr, x + radius, y + height - radius, radius, 3 * (G_PI / 4), G_PI);
91 }
92 else if ((sides & SIDE_BOTTOM) == 0)
93 cairo_move_to (cr, x, y + height);
94
95 if (radius == 0 ||
96 (junction & GTK_JUNCTION_CORNER_TOPLEFT))
97 cairo_line_to (cr, x, y);
98 else
99 cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI + G_PI / 4);
100 }
101
102 if (sides & SIDE_TOP)
103 {
104 if (radius != 0 &&
105 ! (junction & GTK_JUNCTION_CORNER_TOPLEFT))
106 {
107 if ((sides & SIDE_LEFT) == 0)
108 cairo_new_sub_path (cr);
109
110 cairo_arc (cr, x + radius, y + radius, radius, 5 * (G_PI / 4), 3 * (G_PI / 2));
111 }
112 else if ((sides & SIDE_LEFT) == 0)
113 cairo_move_to (cr, x, y);
114
115 if (radius == 0 ||
116 (junction & GTK_JUNCTION_CORNER_TOPRIGHT))
117 cairo_line_to (cr, x + width, y);
118 else
119 cairo_arc (cr, x + width - radius, y + radius, radius, 3 * (G_PI / 2), - G_PI / 4);
120 }
121 }
122
123 void
unico_cairo_round_rect_inner(cairo_t * cr,gdouble x,gdouble y,gdouble width,gdouble height,gint radius,guint sides,GtkJunctionSides junction)124 unico_cairo_round_rect_inner (cairo_t *cr,
125 gdouble x,
126 gdouble y,
127 gdouble width,
128 gdouble height,
129 gint radius,
130 guint sides,
131 GtkJunctionSides junction)
132 {
133 gdouble line_width;
134
135 line_width = cairo_get_line_width (cr);
136
137 /* center the rounded rectangle using line_width */
138 unico_cairo_round_rect (cr, x + line_width / 2.0,
139 y + line_width / 2.0,
140 width - line_width,
141 height - line_width,
142 radius, sides, junction);
143 }
144