]> Pileus Git - ~andy/gtk/blob - gtk/gtkroundedbox.c
Require XInput2.h in X11 backend
[~andy/gtk] / gtk / gtkroundedbox.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2011 Benjamin Otte <otte@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include "gtkroundedboxprivate.h"
21 #include "gtkthemingengineprivate.h"
22
23 #include <string.h>
24
25 /**
26  * _gtk_rounded_box_init_rect:
27  * @box: box to initialize
28  * @x: x coordinate of box
29  * @y: y coordinate of box
30  * @width: width of box
31  * @height: height of box
32  *
33  * Initializes the given @box to represent the given rectangle.
34  * The
35  **/
36 void
37 _gtk_rounded_box_init_rect (GtkRoundedBox *box,
38                             double         x,
39                             double         y,
40                             double         width,
41                             double         height)
42 {
43   memset (box, 0, sizeof (GtkRoundedBox));
44
45   box->box.x = x;
46   box->box.y = y;
47   box->box.width = width;
48   box->box.height = height;
49 }
50
51 /* clamp border radius, following CSS specs */
52 static void
53 gtk_rounded_box_clamp_border_radius (GtkRoundedBox *box)
54 {
55   gdouble factor = 1.0;
56
57   /* note: division by zero leads to +INF, which is > factor, so will be ignored */
58   factor = MIN (factor, box->box.width / (box->corner[GTK_CSS_TOP_LEFT].horizontal +
59                                           box->corner[GTK_CSS_TOP_RIGHT].horizontal));
60   factor = MIN (factor, box->box.height / (box->corner[GTK_CSS_TOP_RIGHT].vertical +
61                                            box->corner[GTK_CSS_BOTTOM_RIGHT].vertical));
62   factor = MIN (factor, box->box.width / (box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal +
63                                           box->corner[GTK_CSS_BOTTOM_LEFT].horizontal));
64   factor = MIN (factor, box->box.height / (box->corner[GTK_CSS_TOP_LEFT].vertical +
65                                            box->corner[GTK_CSS_BOTTOM_LEFT].vertical));
66
67   box->corner[GTK_CSS_TOP_LEFT].horizontal *= factor;
68   box->corner[GTK_CSS_TOP_LEFT].vertical *= factor;
69   box->corner[GTK_CSS_TOP_RIGHT].horizontal *= factor;
70   box->corner[GTK_CSS_TOP_RIGHT].vertical *= factor;
71   box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal *= factor;
72   box->corner[GTK_CSS_BOTTOM_RIGHT].vertical *= factor;
73   box->corner[GTK_CSS_BOTTOM_LEFT].horizontal *= factor;
74   box->corner[GTK_CSS_BOTTOM_LEFT].vertical *= factor;
75 }
76
77 void
78 _gtk_rounded_box_apply_border_radius (GtkRoundedBox *box,
79                                       GtkCssBorderCornerRadius **corner,
80                                       GtkJunctionSides junction)
81 {
82   if (corner[GTK_CSS_TOP_LEFT] && (junction & GTK_JUNCTION_CORNER_TOPLEFT) == 0)
83     {
84       box->corner[GTK_CSS_TOP_LEFT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_TOP_LEFT]->horizontal,
85                                                                       box->box.width);
86       box->corner[GTK_CSS_TOP_LEFT].vertical = _gtk_css_number_get (&corner[GTK_CSS_TOP_LEFT]->vertical,
87                                                                     box->box.height);
88     }
89   if (corner[GTK_CSS_TOP_RIGHT] && (junction & GTK_JUNCTION_CORNER_TOPRIGHT) == 0)
90     {
91       box->corner[GTK_CSS_TOP_RIGHT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_TOP_RIGHT]->horizontal,
92                                                                        box->box.width);
93       box->corner[GTK_CSS_TOP_RIGHT].vertical = _gtk_css_number_get (&corner[GTK_CSS_TOP_RIGHT]->vertical,
94                                                                      box->box.height);
95     }
96   if (corner[GTK_CSS_BOTTOM_RIGHT] && (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT) == 0)
97     {
98       box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_RIGHT]->horizontal,
99                                                                           box->box.width);
100       box->corner[GTK_CSS_BOTTOM_RIGHT].vertical = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_RIGHT]->vertical,
101                                                                         box->box.height);
102     }
103   if (corner[GTK_CSS_BOTTOM_LEFT] && (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) == 0)
104     {
105       box->corner[GTK_CSS_BOTTOM_LEFT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_LEFT]->horizontal,
106                                                                          box->box.width);
107       box->corner[GTK_CSS_BOTTOM_LEFT].vertical = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_LEFT]->vertical,
108                                                                        box->box.height);
109     }
110
111   gtk_rounded_box_clamp_border_radius (box);
112 }
113
114 void
115 _gtk_rounded_box_apply_border_radius_for_context (GtkRoundedBox    *box,
116                                                   GtkStyleContext  *context,
117                                                   GtkStateFlags     state,
118                                                   GtkJunctionSides  junction)
119 {
120   GtkCssBorderCornerRadius *corner[4];
121   guint i;
122
123   gtk_style_context_get (context, state,
124                          /* Can't use border-radius as it's an int for
125                           * backwards compat */
126                          "border-top-left-radius", &corner[GTK_CSS_TOP_LEFT],
127                          "border-top-right-radius", &corner[GTK_CSS_TOP_RIGHT],
128                          "border-bottom-right-radius", &corner[GTK_CSS_BOTTOM_RIGHT],
129                          "border-bottom-left-radius", &corner[GTK_CSS_BOTTOM_LEFT],
130                          NULL);
131
132   _gtk_rounded_box_apply_border_radius (box, corner, junction);
133
134   for (i = 0; i < 4; i++)
135     g_free (corner[i]);
136 }
137
138 void
139 _gtk_rounded_box_apply_border_radius_for_engine (GtkRoundedBox    *box,
140                                                  GtkThemingEngine *engine,
141                                                  GtkStateFlags     state,
142                                                  GtkJunctionSides  junction)
143 {
144   _gtk_rounded_box_apply_border_radius_for_context (box, _gtk_theming_engine_get_context (engine),
145                                                     state, junction);
146 }
147
148 static void
149 gtk_css_border_radius_grow (GtkRoundedBoxCorner *corner,
150                             double               horizontal,
151                             double               vertical)
152 {
153   corner->horizontal += horizontal;
154   corner->vertical += vertical;
155
156   if (corner->horizontal <= 0 || corner->vertical <= 0)
157     {
158       corner->horizontal = 0;
159       corner->vertical = 0;
160     }
161 }
162 void
163 _gtk_rounded_box_grow (GtkRoundedBox *box,
164                        double         top,
165                        double         right,
166                        double         bottom,
167                        double         left)
168 {
169   if (box->box.width + left + right < 0)
170     {
171       box->box.x -= left * box->box.width / (left + right);
172       box->box.width = 0;
173     }
174   else
175     {
176       box->box.x -= left;
177       box->box.width += left + right;
178     }
179
180   if (box->box.height + bottom + right < 0)
181     {
182       box->box.y -= top * box->box.height / (top + bottom);
183       box->box.height = 0;
184     }
185   else
186     {
187       box->box.y -= top;
188       box->box.height += top + bottom;
189     }
190
191   gtk_css_border_radius_grow (&box->corner[GTK_CSS_TOP_LEFT], left, top);
192   gtk_css_border_radius_grow (&box->corner[GTK_CSS_TOP_RIGHT], right, bottom);
193   gtk_css_border_radius_grow (&box->corner[GTK_CSS_BOTTOM_RIGHT], right, top);
194   gtk_css_border_radius_grow (&box->corner[GTK_CSS_BOTTOM_LEFT], left, bottom);
195 }
196
197 void
198 _gtk_rounded_box_shrink (GtkRoundedBox *box,
199                          double         top,
200                          double         right,
201                          double         bottom,
202                          double         left)
203 {
204   _gtk_rounded_box_grow (box, -top, -right, -bottom, -left);
205 }
206
207 void
208 _gtk_rounded_box_move (GtkRoundedBox *box,
209                        double         dx,
210                        double         dy)
211 {
212   box->box.x += dx;
213   box->box.y += dy;
214 }
215
216 static void
217 _cairo_ellipsis (cairo_t *cr,
218                  double xc, double yc,
219                  double xradius, double yradius,
220                  double angle1, double angle2)
221 {
222   if (xradius <= 0.0 || yradius <= 0.0)
223     {
224       cairo_line_to (cr, xc, yc);
225       return;
226     }
227
228   cairo_save (cr);
229   cairo_translate (cr, xc, yc);
230   cairo_scale (cr, xradius, yradius);
231   cairo_arc (cr, 0, 0, 1.0, angle1, angle2);
232   cairo_restore (cr);
233 }
234
235 static void
236 _cairo_ellipsis_negative (cairo_t *cr,
237                           double xc, double yc,
238                           double xradius, double yradius,
239                           double angle1, double angle2)
240 {
241   if (xradius <= 0.0 || yradius <= 0.0)
242     {
243       cairo_line_to (cr, xc, yc);
244       return;
245     }
246
247   cairo_save (cr);
248   cairo_translate (cr, xc, yc);
249   cairo_scale (cr, xradius, yradius);
250   cairo_arc_negative (cr, 0, 0, 1.0, angle1, angle2);
251   cairo_restore (cr);
252 }
253
254 void
255 _gtk_rounded_box_path (const GtkRoundedBox *box,
256                        cairo_t             *cr)
257 {
258   cairo_new_sub_path (cr);
259
260   _cairo_ellipsis (cr,
261                    box->box.x + box->corner[GTK_CSS_TOP_LEFT].horizontal,
262                    box->box.y + box->corner[GTK_CSS_TOP_LEFT].vertical,
263                    box->corner[GTK_CSS_TOP_LEFT].horizontal,
264                    box->corner[GTK_CSS_TOP_LEFT].vertical,
265                    G_PI, 3 * G_PI / 2);
266   _cairo_ellipsis (cr, 
267                    box->box.x + box->box.width - box->corner[GTK_CSS_TOP_RIGHT].horizontal,
268                    box->box.y + box->corner[GTK_CSS_TOP_RIGHT].vertical,
269                    box->corner[GTK_CSS_TOP_RIGHT].horizontal,
270                    box->corner[GTK_CSS_TOP_RIGHT].vertical,
271                    - G_PI / 2, 0);
272   _cairo_ellipsis (cr,
273                    box->box.x + box->box.width - box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
274                    box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
275                    box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
276                    box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
277                    0, G_PI / 2);
278   _cairo_ellipsis (cr,
279                    box->box.x + box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
280                    box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
281                    box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
282                    box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
283                    G_PI / 2, G_PI);
284
285   cairo_close_path (cr);
286 }
287
288 double
289 _gtk_rounded_box_guess_length (const GtkRoundedBox *box,
290                                GtkCssSide           side)
291 {
292   double length;
293   GtkCssCorner before, after;
294
295   before = side;
296   after = (side + 1) % 4;
297
298   if (side & 1)
299     length = box->box.height
300              - box->corner[before].vertical
301              - box->corner[after].vertical;
302   else
303     length = box->box.width
304              - box->corner[before].horizontal
305              - box->corner[after].horizontal;
306
307   length += G_PI * 0.125 * (box->corner[before].horizontal
308                             + box->corner[before].vertical
309                             + box->corner[after].horizontal
310                             + box->corner[after].vertical);
311
312   return length;
313 }
314
315 void
316 _gtk_rounded_box_path_side (const GtkRoundedBox *box,
317                             cairo_t             *cr,
318                             GtkCssSide           side)
319 {
320   switch (side)
321     {
322     case GTK_CSS_TOP:
323       _cairo_ellipsis (cr,
324                        box->box.x + box->corner[GTK_CSS_TOP_LEFT].horizontal,
325                        box->box.y + box->corner[GTK_CSS_TOP_LEFT].vertical,
326                        box->corner[GTK_CSS_TOP_LEFT].horizontal,
327                        box->corner[GTK_CSS_TOP_LEFT].vertical,
328                        5 * G_PI / 4, 3 * G_PI / 2);
329       _cairo_ellipsis (cr, 
330                        box->box.x + box->box.width - box->corner[GTK_CSS_TOP_RIGHT].horizontal,
331                        box->box.y + box->corner[GTK_CSS_TOP_RIGHT].vertical,
332                        box->corner[GTK_CSS_TOP_RIGHT].horizontal,
333                        box->corner[GTK_CSS_TOP_RIGHT].vertical,
334                        - G_PI / 2, -G_PI / 4);
335       break;
336     case GTK_CSS_RIGHT:
337       _cairo_ellipsis (cr, 
338                        box->box.x + box->box.width - box->corner[GTK_CSS_TOP_RIGHT].horizontal,
339                        box->box.y + box->corner[GTK_CSS_TOP_RIGHT].vertical,
340                        box->corner[GTK_CSS_TOP_RIGHT].horizontal,
341                        box->corner[GTK_CSS_TOP_RIGHT].vertical,
342                        - G_PI / 4, 0);
343       _cairo_ellipsis (cr,
344                        box->box.x + box->box.width - box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
345                        box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
346                        box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
347                        box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
348                        0, G_PI / 4);
349       break;
350     case GTK_CSS_BOTTOM:
351       _cairo_ellipsis (cr,
352                        box->box.x + box->box.width - box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
353                        box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
354                        box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
355                        box->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
356                        G_PI / 4, G_PI / 2);
357       _cairo_ellipsis (cr,
358                        box->box.x + box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
359                        box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
360                        box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
361                        box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
362                        G_PI / 2, 3 * G_PI / 4);
363       break;
364     case GTK_CSS_LEFT:
365       _cairo_ellipsis (cr,
366                        box->box.x + box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
367                        box->box.y + box->box.height - box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
368                        box->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
369                        box->corner[GTK_CSS_BOTTOM_LEFT].vertical,
370                        3 * G_PI / 4, G_PI);
371       _cairo_ellipsis (cr,
372                        box->box.x + box->corner[GTK_CSS_TOP_LEFT].horizontal,
373                        box->box.y + box->corner[GTK_CSS_TOP_LEFT].vertical,
374                        box->corner[GTK_CSS_TOP_LEFT].horizontal,
375                        box->corner[GTK_CSS_TOP_LEFT].vertical,
376                        G_PI, 5 * G_PI / 4);
377       break;
378     default:
379       g_assert_not_reached ();
380       break;
381     }
382 }
383
384 void
385 _gtk_rounded_box_path_top (const GtkRoundedBox *outer,
386                            const GtkRoundedBox *inner,
387                            cairo_t             *cr)
388 {
389   cairo_new_sub_path (cr);
390
391   _cairo_ellipsis (cr,
392                    outer->box.x + outer->corner[GTK_CSS_TOP_LEFT].horizontal,
393                    outer->box.y + outer->corner[GTK_CSS_TOP_LEFT].vertical,
394                    outer->corner[GTK_CSS_TOP_LEFT].horizontal,
395                    outer->corner[GTK_CSS_TOP_LEFT].vertical,
396                    5 * G_PI / 4, 3 * G_PI / 2);
397   _cairo_ellipsis (cr, 
398                    outer->box.x + outer->box.width - outer->corner[GTK_CSS_TOP_RIGHT].horizontal,
399                    outer->box.y + outer->corner[GTK_CSS_TOP_RIGHT].vertical,
400                    outer->corner[GTK_CSS_TOP_RIGHT].horizontal,
401                    outer->corner[GTK_CSS_TOP_RIGHT].vertical,
402                    - G_PI / 2, -G_PI / 4);
403
404   _cairo_ellipsis_negative (cr, 
405                             inner->box.x + inner->box.width - inner->corner[GTK_CSS_TOP_RIGHT].horizontal,
406                             inner->box.y + inner->corner[GTK_CSS_TOP_RIGHT].vertical,
407                             inner->corner[GTK_CSS_TOP_RIGHT].horizontal,
408                             inner->corner[GTK_CSS_TOP_RIGHT].vertical,
409                             -G_PI / 4, - G_PI / 2);
410   _cairo_ellipsis_negative (cr,
411                             inner->box.x + inner->corner[GTK_CSS_TOP_LEFT].horizontal,
412                             inner->box.y + inner->corner[GTK_CSS_TOP_LEFT].vertical,
413                             inner->corner[GTK_CSS_TOP_LEFT].horizontal,
414                             inner->corner[GTK_CSS_TOP_LEFT].vertical,
415                             3 * G_PI / 2, 5 * G_PI / 4);
416
417   cairo_close_path (cr);
418 }
419
420 void
421 _gtk_rounded_box_path_right (const GtkRoundedBox *outer,
422                              const GtkRoundedBox *inner,
423                              cairo_t             *cr)
424 {
425   cairo_new_sub_path (cr);
426
427   _cairo_ellipsis (cr, 
428                    outer->box.x + outer->box.width - outer->corner[GTK_CSS_TOP_RIGHT].horizontal,
429                    outer->box.y + outer->corner[GTK_CSS_TOP_RIGHT].vertical,
430                    outer->corner[GTK_CSS_TOP_RIGHT].horizontal,
431                    outer->corner[GTK_CSS_TOP_RIGHT].vertical,
432                    - G_PI / 4, 0);
433   _cairo_ellipsis (cr,
434                    outer->box.x + outer->box.width - outer->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
435                    outer->box.y + outer->box.height - outer->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
436                    outer->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
437                    outer->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
438                    0, G_PI / 4);
439
440   _cairo_ellipsis_negative (cr,
441                             inner->box.x + inner->box.width - inner->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
442                             inner->box.y + inner->box.height - inner->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
443                             inner->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
444                             inner->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
445                             G_PI / 4, 0);
446   _cairo_ellipsis_negative (cr, 
447                             inner->box.x + inner->box.width - inner->corner[GTK_CSS_TOP_RIGHT].horizontal,
448                             inner->box.y + inner->corner[GTK_CSS_TOP_RIGHT].vertical,
449                             inner->corner[GTK_CSS_TOP_RIGHT].horizontal,
450                             inner->corner[GTK_CSS_TOP_RIGHT].vertical,
451                             0, - G_PI / 4);
452
453   cairo_close_path (cr);
454 }
455
456 void
457 _gtk_rounded_box_path_bottom (const GtkRoundedBox *outer,
458                               const GtkRoundedBox *inner,
459                               cairo_t             *cr)
460 {
461   cairo_new_sub_path (cr);
462
463   _cairo_ellipsis (cr,
464                    outer->box.x + outer->box.width - outer->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
465                    outer->box.y + outer->box.height - outer->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
466                    outer->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
467                    outer->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
468                    G_PI / 4, G_PI / 2);
469   _cairo_ellipsis (cr,
470                    outer->box.x + outer->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
471                    outer->box.y + outer->box.height - outer->corner[GTK_CSS_BOTTOM_LEFT].vertical,
472                    outer->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
473                    outer->corner[GTK_CSS_BOTTOM_LEFT].vertical,
474                    G_PI / 2, 3 * G_PI / 4);
475
476   _cairo_ellipsis_negative (cr,
477                             inner->box.x + inner->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
478                             inner->box.y + inner->box.height - inner->corner[GTK_CSS_BOTTOM_LEFT].vertical,
479                             inner->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
480                             inner->corner[GTK_CSS_BOTTOM_LEFT].vertical,
481                             3 * G_PI / 4, G_PI / 2);
482   _cairo_ellipsis_negative (cr,
483                             inner->box.x + inner->box.width - inner->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
484                             inner->box.y + inner->box.height - inner->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
485                             inner->corner[GTK_CSS_BOTTOM_RIGHT].horizontal,
486                             inner->corner[GTK_CSS_BOTTOM_RIGHT].vertical,
487                             G_PI / 2, G_PI / 4);
488
489   cairo_close_path (cr);
490 }
491
492 void
493 _gtk_rounded_box_path_left (const GtkRoundedBox *outer,
494                             const GtkRoundedBox *inner,
495                             cairo_t             *cr)
496 {
497   cairo_new_sub_path (cr);
498
499   _cairo_ellipsis (cr,
500                    outer->box.x + outer->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
501                    outer->box.y + outer->box.height - outer->corner[GTK_CSS_BOTTOM_LEFT].vertical,
502                    outer->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
503                    outer->corner[GTK_CSS_BOTTOM_LEFT].vertical,
504                    3 * G_PI / 4, G_PI);
505   _cairo_ellipsis (cr,
506                    outer->box.x + outer->corner[GTK_CSS_TOP_LEFT].horizontal,
507                    outer->box.y + outer->corner[GTK_CSS_TOP_LEFT].vertical,
508                    outer->corner[GTK_CSS_TOP_LEFT].horizontal,
509                    outer->corner[GTK_CSS_TOP_LEFT].vertical,
510                    G_PI, 5 * G_PI / 4);
511
512   _cairo_ellipsis_negative (cr,
513                             inner->box.x + inner->corner[GTK_CSS_TOP_LEFT].horizontal,
514                             inner->box.y + inner->corner[GTK_CSS_TOP_LEFT].vertical,
515                             inner->corner[GTK_CSS_TOP_LEFT].horizontal,
516                             inner->corner[GTK_CSS_TOP_LEFT].vertical,
517                             5 * G_PI / 4, G_PI);
518   _cairo_ellipsis_negative (cr,
519                             inner->box.x + inner->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
520                             inner->box.y + inner->box.height - inner->corner[GTK_CSS_BOTTOM_LEFT].vertical,
521                             inner->corner[GTK_CSS_BOTTOM_LEFT].horizontal,
522                             inner->corner[GTK_CSS_BOTTOM_LEFT].vertical,
523                             G_PI, 3 * G_PI / 4);
524
525   cairo_close_path (cr);
526 }
527
528 void
529 _gtk_rounded_box_clip_path (const GtkRoundedBox *box,
530                             cairo_t             *cr)
531 {
532   cairo_rectangle (cr,
533                    box->box.x, box->box.y,
534                    box->box.width, box->box.height);
535 }
536