271
/* To match the CSS specification, we want the border to look like it was
272
* drawn over the background. But actually drawing the border over the
273
* background will produce slightly bad antialiasing at the edges, so
274
* compute the effective border color instead.
276
#define NORM(x) (t = (x) + 127, (t + (t >> 8)) >> 8)
277
#define MULT(c,a) NORM(c*a)
280
premultiply (ClutterColor *color)
283
color->red = MULT (color->red, color->alpha);
284
color->green = MULT (color->green, color->alpha);
285
color->blue = MULT (color->blue, color->alpha);
289
unpremultiply (ClutterColor *color)
291
if (color->alpha != 0) {
292
color->red = (color->red * 255 + 127) / color->alpha;
293
color->green = (color->green * 255 + 127) / color->alpha;
294
color->blue = (color->blue * 255 + 127) / color->alpha;
299
over (const ClutterColor *source,
300
const ClutterColor *destination,
301
ClutterColor *result)
304
ClutterColor src = *source;
305
ClutterColor dst = *destination;
309
result->alpha = src.alpha + NORM ((255 - src.alpha) * dst.alpha);
310
result->red = src.red + NORM ((255 - src.alpha) * dst.red);
311
result->green = src.green + NORM ((255 - src.alpha) * dst.green);
312
result->blue = src.blue + NORM ((255 - src.alpha) * dst.blue);
314
unpremultiply (result);
272
318
big_rectangle_update_corners(BigRectangle *rectangle)
336
over (border_color, color, &effective_border);
289
338
corner = corner_get(rectangle->radius,
294
343
clutter_color_free(border_color);
295
344
clutter_color_free(color);
330
379
rectangle = BIG_RECTANGLE(actor);
332
if (rectangle->radius == 0) {
333
/* In that case we are no different than our parent class,
335
CLUTTER_ACTOR_CLASS(big_rectangle_parent_class)->paint(actor);
381
/* We can't chain up, even when we the radius is 0, because of the different
382
* interpretation of the border/background relationship here than for
339
386
if (rectangle->corners_dirty)
340
387
big_rectangle_update_corners(rectangle);
359
409
radius = rectangle->radius;
411
/* Optimization; if the border is transparent, it just looks like part of
413
if (radius == 0 && border_color->alpha == 0)
361
416
max = MAX(border_width, radius);
363
418
if (radius != 0) {
395
450
if (border_width != 0) {
451
ClutterColor effective_border;
452
over (border_color, color, &effective_border);
396
454
if (!rectangle->border_material)
397
455
rectangle->border_material = cogl_material_new ();
399
457
cogl_color_set_from_4ub(&tmp_color,
403
actor_opacity * border_color->alpha / 255);
458
effective_border.red,
459
effective_border.green,
460
effective_border.blue,
461
actor_opacity * effective_border.alpha / 255);
404
462
cogl_color_premultiply (&tmp_color);
405
463
cogl_material_set_color(rectangle->border_material, &tmp_color);
406
464
cogl_set_source(rectangle->border_material);
409
cogl_rectangle(max, 0,
410
width - max, border_width);
413
cogl_rectangle(width - border_width, max,
414
width, height - max);
417
cogl_rectangle(max, height - border_width,
418
width - max, height);
421
cogl_rectangle(0, max,
422
border_width, height - max);
466
if (radius > 0) { /* skip corners */
468
cogl_rectangle(max, 0,
469
width - max, border_width);
472
cogl_rectangle(width - border_width, max,
473
width, height - max);
476
cogl_rectangle(max, height - border_width,
477
width - max, height);
480
cogl_rectangle(0, max,
481
border_width, height - max);
482
} else { /* include corners */
485
width, border_width);
488
cogl_rectangle(width - border_width, border_width,
489
width, height - border_width);
492
cogl_rectangle(0, height - border_width,
496
cogl_rectangle(0, border_width,
497
border_width, height - border_width);
425
501
if (!rectangle->background_material)
455
531
cogl_rectangle(border_width, max,
456
532
width - border_width, height - max);
458
535
clutter_color_free(border_color);
459
536
clutter_color_free(color);