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