~mterry/ubuntu/natty/gnome-shell/wip

« back to all changes in this revision

Viewing changes to src/big/rectangle.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2009-10-12 22:44:00 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091012224400-k91p42yvou07i525
Tags: 2.28.0-0ubuntu1
* New upstream version
* debian/control:
  - updated build requirement
* debian/patches/80_git_change_fix_alt_tab_ressource_usage.patch:
  - git change to fix ressources not being freed on alt-tab

Show diffs side-by-side

added added

removed removed

Lines of Context:
268
268
    return corner;
269
269
}
270
270
 
 
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.
 
275
 */
 
276
#define NORM(x) (t = (x) + 127, (t + (t >> 8)) >> 8)
 
277
#define MULT(c,a) NORM(c*a)
 
278
 
 
279
static void
 
280
premultiply (ClutterColor *color)
 
281
{
 
282
    guint t;
 
283
    color->red = MULT (color->red, color->alpha);
 
284
    color->green = MULT (color->green, color->alpha);
 
285
    color->blue = MULT (color->blue, color->alpha);
 
286
}
 
287
 
 
288
static void
 
289
unpremultiply (ClutterColor *color)
 
290
{
 
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;
 
295
    }
 
296
}
 
297
 
 
298
static void
 
299
over (const ClutterColor *source,
 
300
      const ClutterColor *destination,
 
301
      ClutterColor       *result)
 
302
{
 
303
    guint t;
 
304
    ClutterColor src = *source;
 
305
    ClutterColor dst = *destination;
 
306
    premultiply (&src);
 
307
    premultiply (&dst);
 
308
 
 
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);
 
313
 
 
314
    unpremultiply (result);
 
315
}
 
316
 
271
317
static void
272
318
big_rectangle_update_corners(BigRectangle *rectangle)
273
319
{
278
324
    if (rectangle->radius != 0) {
279
325
        ClutterColor *color;
280
326
        ClutterColor *border_color;
 
327
        ClutterColor effective_border;
281
328
        guint border_width;
282
329
 
283
330
        g_object_get(rectangle,
286
333
                     "color", &color,
287
334
                     NULL);
288
335
 
 
336
        over (border_color, color, &effective_border);
 
337
 
289
338
        corner = corner_get(rectangle->radius,
290
339
                            color,
291
340
                            border_width,
292
 
                            border_color);
 
341
                            &effective_border);
293
342
 
294
343
        clutter_color_free(border_color);
295
344
        clutter_color_free(color);
329
378
 
330
379
    rectangle = BIG_RECTANGLE(actor);
331
380
 
332
 
    if (rectangle->radius == 0) {
333
 
        /* In that case we are no different than our parent class,
334
 
         * so don't bother */
335
 
        CLUTTER_ACTOR_CLASS(big_rectangle_parent_class)->paint(actor);
336
 
        return;
337
 
    }
 
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
 
383
     * ClutterRectangle.
 
384
     */
338
385
 
339
386
    if (rectangle->corners_dirty)
340
387
        big_rectangle_update_corners(rectangle);
345
392
                 "color", &color,
346
393
                 NULL);
347
394
 
 
395
    if (border_color->alpha == 0 && color->alpha == 0)
 
396
        goto out;
 
397
 
348
398
    actor_opacity = clutter_actor_get_paint_opacity (actor);
349
399
 
350
400
    clutter_actor_get_allocation_box(actor, &box);
358
408
 
359
409
    radius = rectangle->radius;
360
410
 
 
411
    /* Optimization; if the border is transparent, it just looks like part of
 
412
     * the background */
 
413
    if (radius == 0 && border_color->alpha == 0)
 
414
        border_width = 0;
 
415
 
361
416
    max = MAX(border_width, radius);
362
417
 
363
418
    if (radius != 0) {
393
448
    }
394
449
 
395
450
    if (border_width != 0) {
 
451
        ClutterColor effective_border;
 
452
        over (border_color, color, &effective_border);
 
453
 
396
454
        if (!rectangle->border_material)
397
455
            rectangle->border_material = cogl_material_new ();
398
456
 
399
457
        cogl_color_set_from_4ub(&tmp_color,
400
 
                                border_color->red,
401
 
                                border_color->green,
402
 
                                border_color->blue,
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);
407
465
 
408
 
        /* NORTH */
409
 
        cogl_rectangle(max, 0,
410
 
                       width - max, border_width);
411
 
 
412
 
        /* EAST */
413
 
        cogl_rectangle(width - border_width, max,
414
 
                       width, height - max);
415
 
 
416
 
        /* SOUTH */
417
 
        cogl_rectangle(max, height - border_width,
418
 
                       width - max, height);
419
 
 
420
 
        /* WEST */
421
 
        cogl_rectangle(0, max,
422
 
                       border_width, height - max);
 
466
        if (radius > 0) { /* skip corners */
 
467
            /* NORTH */
 
468
            cogl_rectangle(max, 0,
 
469
                           width - max, border_width);
 
470
 
 
471
            /* EAST */
 
472
            cogl_rectangle(width - border_width, max,
 
473
                           width, height - max);
 
474
 
 
475
            /* SOUTH */
 
476
            cogl_rectangle(max, height - border_width,
 
477
                           width - max, height);
 
478
 
 
479
            /* WEST */
 
480
            cogl_rectangle(0, max,
 
481
                           border_width, height - max);
 
482
        } else { /* include corners */
 
483
            /* NORTH */
 
484
            cogl_rectangle(0, 0,
 
485
                           width, border_width);
 
486
 
 
487
            /* EAST */
 
488
            cogl_rectangle(width - border_width, border_width,
 
489
                           width, height - border_width);
 
490
 
 
491
            /* SOUTH */
 
492
            cogl_rectangle(0, height - border_width,
 
493
                           width, height);
 
494
 
 
495
            /* WEST */
 
496
            cogl_rectangle(0, border_width,
 
497
                           border_width, height - border_width);
 
498
        }
423
499
    }
424
500
 
425
501
    if (!rectangle->background_material)
455
531
    cogl_rectangle(border_width, max,
456
532
                   width - border_width, height - max);
457
533
 
 
534
out:
458
535
    clutter_color_free(border_color);
459
536
    clutter_color_free(color);
460
537
}