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