173a2ffbaSStephan Aßmus /*
273a2ffbaSStephan Aßmus * Copyright 2006, Haiku. All rights reserved.
373a2ffbaSStephan Aßmus * Distributed under the terms of the MIT License.
473a2ffbaSStephan Aßmus *
573a2ffbaSStephan Aßmus * Authors:
673a2ffbaSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de>
773a2ffbaSStephan Aßmus */
873a2ffbaSStephan Aßmus
936947c7bSOliver Tappe
1073a2ffbaSStephan Aßmus #include "Layer.h"
1173a2ffbaSStephan Aßmus
1273a2ffbaSStephan Aßmus #include <stdio.h>
1373a2ffbaSStephan Aßmus
1473a2ffbaSStephan Aßmus #include <Bitmap.h>
156537cf97SJérôme Duval #include <Catalog.h>
1673a2ffbaSStephan Aßmus #include <Message.h>
1773a2ffbaSStephan Aßmus
1873a2ffbaSStephan Aßmus #include "bitmap_compression.h"
1973a2ffbaSStephan Aßmus #include "blending.h"
2073a2ffbaSStephan Aßmus #include "lab_convert.h"
2173a2ffbaSStephan Aßmus #include "support.h"
2273a2ffbaSStephan Aßmus
2336947c7bSOliver Tappe
24*546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
25*546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Layer"
266537cf97SJérôme Duval
276537cf97SJérôme Duval
2873a2ffbaSStephan Aßmus // constructor
Layer()2973a2ffbaSStephan Aßmus Layer::Layer()
3073a2ffbaSStephan Aßmus : fBitmap(NULL),
3173a2ffbaSStephan Aßmus fBounds(0.0, 0.0, -1.0, -1.0),
3273a2ffbaSStephan Aßmus fAlpha(1.0),
3373a2ffbaSStephan Aßmus fMode(MODE_NORMAL),
3473a2ffbaSStephan Aßmus fFlags(0)
3573a2ffbaSStephan Aßmus {
3673a2ffbaSStephan Aßmus }
3773a2ffbaSStephan Aßmus
3836947c7bSOliver Tappe
3973a2ffbaSStephan Aßmus // destructor
~Layer()4073a2ffbaSStephan Aßmus Layer::~Layer()
4173a2ffbaSStephan Aßmus {
4273a2ffbaSStephan Aßmus delete fBitmap;
4373a2ffbaSStephan Aßmus }
4473a2ffbaSStephan Aßmus
4536947c7bSOliver Tappe
4673a2ffbaSStephan Aßmus // Compose
4773a2ffbaSStephan Aßmus status_t
Compose(const BBitmap * into,BRect area)4873a2ffbaSStephan Aßmus Layer::Compose(const BBitmap* into, BRect area)
4973a2ffbaSStephan Aßmus {
5073a2ffbaSStephan Aßmus if (!fBitmap || !fBitmap->IsValid()
5136947c7bSOliver Tappe || (fBitmap->ColorSpace() != B_RGBA32
5236947c7bSOliver Tappe && fBitmap->ColorSpace() != B_RGB32))
5373a2ffbaSStephan Aßmus return B_NO_INIT;
5473a2ffbaSStephan Aßmus
5573a2ffbaSStephan Aßmus status_t status = B_BAD_VALUE;
5673a2ffbaSStephan Aßmus if (!into || !area.IsValid() || (status = into->InitCheck()) < B_OK)
5773a2ffbaSStephan Aßmus return status;
5873a2ffbaSStephan Aßmus
5973a2ffbaSStephan Aßmus // make sure we don't access memory outside of our bitmap
6073a2ffbaSStephan Aßmus area = area & fBitmap->Bounds();
6173a2ffbaSStephan Aßmus
6273a2ffbaSStephan Aßmus BRect r = ActiveBounds();
6373a2ffbaSStephan Aßmus if (!r.IsValid() || (fFlags & FLAG_INVISIBLE) || !r.Intersects(area))
6473a2ffbaSStephan Aßmus return B_OK;
6573a2ffbaSStephan Aßmus
6673a2ffbaSStephan Aßmus r = r & area;
6773a2ffbaSStephan Aßmus int32 left, top, right, bottom;
6873a2ffbaSStephan Aßmus rect_to_int(r, left, top, right, bottom);
6973a2ffbaSStephan Aßmus
7073a2ffbaSStephan Aßmus uint8* src = (uint8*)fBitmap->Bits();
7173a2ffbaSStephan Aßmus uint8* dst = (uint8*)into->Bits();
7273a2ffbaSStephan Aßmus uint32 bpr = into->BytesPerRow();
7373a2ffbaSStephan Aßmus src += 4 * left + bpr * top;
7473a2ffbaSStephan Aßmus dst += 4 * left + bpr * top;
7573a2ffbaSStephan Aßmus uint8 alphaOverride = (uint8)(fAlpha * 255);
7673a2ffbaSStephan Aßmus
7773a2ffbaSStephan Aßmus switch (fMode) {
7873a2ffbaSStephan Aßmus
7973a2ffbaSStephan Aßmus case MODE_SOFT_LIGHT:
8073a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
8173a2ffbaSStephan Aßmus uint8* srcHandle = src;
8273a2ffbaSStephan Aßmus uint8* dstHandle = dst;
8373a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
8473a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
8573a2ffbaSStephan Aßmus uint8 c1 = dstHandle[0] * srcHandle[0] >> 8;
86258b762aSOliver Tappe c1 += dstHandle[0] * (
8736947c7bSOliver Tappe 255 - (
8836947c7bSOliver Tappe (255 - dstHandle[0])
8936947c7bSOliver Tappe * (255 - srcHandle[0])
9036947c7bSOliver Tappe >> 8
9136947c7bSOliver Tappe ) - c1
9236947c7bSOliver Tappe ) >> 8;
9336947c7bSOliver Tappe c1 = (c1 * dstHandle[3]
9436947c7bSOliver Tappe + srcHandle[0] * (255 - dstHandle[3])
9536947c7bSOliver Tappe ) >> 8;
9673a2ffbaSStephan Aßmus
9773a2ffbaSStephan Aßmus uint8 c2 = dstHandle[1] * srcHandle[1] >> 8;
98258b762aSOliver Tappe c2 += dstHandle[1] * (
9936947c7bSOliver Tappe 255 - (
10036947c7bSOliver Tappe (255 - dstHandle[1])
10136947c7bSOliver Tappe * (255 - srcHandle[1])
10236947c7bSOliver Tappe >> 8
10336947c7bSOliver Tappe ) - c2
10436947c7bSOliver Tappe ) >> 8;
10536947c7bSOliver Tappe c2 = (c2 * dstHandle[3]
10636947c7bSOliver Tappe + srcHandle[1] * (255 - dstHandle[3])
10736947c7bSOliver Tappe ) >> 8;
10873a2ffbaSStephan Aßmus
10973a2ffbaSStephan Aßmus uint8 c3 = dstHandle[2] * srcHandle[2] >> 8;
110258b762aSOliver Tappe c3 += dstHandle[2] * (
11136947c7bSOliver Tappe 255 - (
11236947c7bSOliver Tappe (255 - dstHandle[2])
11336947c7bSOliver Tappe * (255 - srcHandle[2])
11436947c7bSOliver Tappe >> 8
11536947c7bSOliver Tappe ) - c3
11636947c7bSOliver Tappe ) >> 8;
11736947c7bSOliver Tappe c3 = (c3 * dstHandle[3]
11836947c7bSOliver Tappe + srcHandle[2] * (255 - dstHandle[3])
11936947c7bSOliver Tappe ) >> 8;
12073a2ffbaSStephan Aßmus
12136947c7bSOliver Tappe blend_colors(dstHandle,
12236947c7bSOliver Tappe (srcHandle[3] * alphaOverride) >> 8, c1, c2, c3);
12373a2ffbaSStephan Aßmus }
12473a2ffbaSStephan Aßmus srcHandle += 4;
12573a2ffbaSStephan Aßmus dstHandle += 4;
12673a2ffbaSStephan Aßmus }
12773a2ffbaSStephan Aßmus src += bpr;
12873a2ffbaSStephan Aßmus dst += bpr;
12973a2ffbaSStephan Aßmus }
13073a2ffbaSStephan Aßmus break;
13173a2ffbaSStephan Aßmus
13273a2ffbaSStephan Aßmus case MODE_LIGHTEN:
13373a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
13473a2ffbaSStephan Aßmus uint8* srcHandle = src;
13573a2ffbaSStephan Aßmus uint8* dstHandle = dst;
13673a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
13773a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
13873a2ffbaSStephan Aßmus // compose
13936947c7bSOliver Tappe uint8 c1
14036947c7bSOliver Tappe = (max_c(srcHandle[0], dstHandle[0]) * dstHandle[3]
14173a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255;
14236947c7bSOliver Tappe uint8 c2
14336947c7bSOliver Tappe = (max_c(srcHandle[1], dstHandle[1]) * dstHandle[3]
14473a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255;
14536947c7bSOliver Tappe uint8 c3
14636947c7bSOliver Tappe = (max_c(srcHandle[2], dstHandle[2]) * dstHandle[3]
14773a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255;
14836947c7bSOliver Tappe blend_colors(dstHandle,
14936947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3);
15073a2ffbaSStephan Aßmus }
15173a2ffbaSStephan Aßmus srcHandle += 4;
15273a2ffbaSStephan Aßmus dstHandle += 4;
15373a2ffbaSStephan Aßmus }
15473a2ffbaSStephan Aßmus src += bpr;
15573a2ffbaSStephan Aßmus dst += bpr;
15673a2ffbaSStephan Aßmus }
15773a2ffbaSStephan Aßmus break;
15873a2ffbaSStephan Aßmus
15973a2ffbaSStephan Aßmus case MODE_DARKEN:
16073a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
16173a2ffbaSStephan Aßmus uint8* srcHandle = src;
16273a2ffbaSStephan Aßmus uint8* dstHandle = dst;
16373a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
16473a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
16573a2ffbaSStephan Aßmus // compose
16636947c7bSOliver Tappe uint8 c1
16736947c7bSOliver Tappe = (min_c(srcHandle[0], dstHandle[0]) * dstHandle[3]
16873a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255;
16936947c7bSOliver Tappe uint8 c2
17036947c7bSOliver Tappe = (min_c(srcHandle[1], dstHandle[1]) * dstHandle[3]
17173a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255;
17236947c7bSOliver Tappe uint8 c3
17336947c7bSOliver Tappe = (min_c(srcHandle[2], dstHandle[2]) * dstHandle[3]
17473a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255;
17536947c7bSOliver Tappe blend_colors(dstHandle,
17636947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3);
17773a2ffbaSStephan Aßmus }
17873a2ffbaSStephan Aßmus srcHandle += 4;
17973a2ffbaSStephan Aßmus dstHandle += 4;
18073a2ffbaSStephan Aßmus }
18173a2ffbaSStephan Aßmus src += bpr;
18273a2ffbaSStephan Aßmus dst += bpr;
18373a2ffbaSStephan Aßmus }
18473a2ffbaSStephan Aßmus break;
18573a2ffbaSStephan Aßmus
18673a2ffbaSStephan Aßmus case MODE_REPLACE_RED:
18773a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
18873a2ffbaSStephan Aßmus uint8* srcHandle = src;
18973a2ffbaSStephan Aßmus uint8* dstHandle = dst;
19073a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
19173a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
19273a2ffbaSStephan Aßmus // compose
19373a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride;
19473a2ffbaSStephan Aßmus dstHandle[2] = (srcHandle[2] * alpha
19573a2ffbaSStephan Aßmus + dstHandle[2] * (65025 - alpha)) / 65025;
19673a2ffbaSStephan Aßmus }
19773a2ffbaSStephan Aßmus srcHandle += 4;
19873a2ffbaSStephan Aßmus dstHandle += 4;
19973a2ffbaSStephan Aßmus }
20073a2ffbaSStephan Aßmus src += bpr;
20173a2ffbaSStephan Aßmus dst += bpr;
20273a2ffbaSStephan Aßmus }
20373a2ffbaSStephan Aßmus break;
20473a2ffbaSStephan Aßmus
20573a2ffbaSStephan Aßmus case MODE_REPLACE_GREEN:
20673a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
20773a2ffbaSStephan Aßmus uint8* srcHandle = src;
20873a2ffbaSStephan Aßmus uint8* dstHandle = dst;
20973a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
21073a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
21173a2ffbaSStephan Aßmus // compose
21273a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride;
21373a2ffbaSStephan Aßmus dstHandle[1] = (srcHandle[1] * alpha
21473a2ffbaSStephan Aßmus + dstHandle[1] * (65025 - alpha)) / 65025;
21573a2ffbaSStephan Aßmus }
21673a2ffbaSStephan Aßmus srcHandle += 4;
21773a2ffbaSStephan Aßmus dstHandle += 4;
21873a2ffbaSStephan Aßmus }
21973a2ffbaSStephan Aßmus src += bpr;
22073a2ffbaSStephan Aßmus dst += bpr;
22173a2ffbaSStephan Aßmus }
22273a2ffbaSStephan Aßmus break;
22373a2ffbaSStephan Aßmus
22473a2ffbaSStephan Aßmus case MODE_REPLACE_BLUE:
22573a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
22673a2ffbaSStephan Aßmus uint8* srcHandle = src;
22773a2ffbaSStephan Aßmus uint8* dstHandle = dst;
22873a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
22973a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
23073a2ffbaSStephan Aßmus // compose
23173a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride;
23273a2ffbaSStephan Aßmus dstHandle[0] = (srcHandle[0] * alpha
23373a2ffbaSStephan Aßmus + dstHandle[0] * (65025 - alpha)) / 65025;
23473a2ffbaSStephan Aßmus }
23573a2ffbaSStephan Aßmus srcHandle += 4;
23673a2ffbaSStephan Aßmus dstHandle += 4;
23773a2ffbaSStephan Aßmus }
23873a2ffbaSStephan Aßmus src += bpr;
23973a2ffbaSStephan Aßmus dst += bpr;
24073a2ffbaSStephan Aßmus }
24173a2ffbaSStephan Aßmus break;
24273a2ffbaSStephan Aßmus
24373a2ffbaSStephan Aßmus case MODE_MULTIPLY_INVERSE_ALPHA:
24473a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
24573a2ffbaSStephan Aßmus uint8* srcHandle = src;
24673a2ffbaSStephan Aßmus uint8* dstHandle = dst;
24773a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
24873a2ffbaSStephan Aßmus // compose
24973a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], 255 - srcHandle[3]);
25036947c7bSOliver Tappe dstHandle[3] = (
25136947c7bSOliver Tappe dstHandle[3] * (255 - alphaOverride)
25236947c7bSOliver Tappe + temp * alphaOverride
25336947c7bSOliver Tappe ) / 255;
25473a2ffbaSStephan Aßmus srcHandle += 4;
25573a2ffbaSStephan Aßmus dstHandle += 4;
25673a2ffbaSStephan Aßmus }
25773a2ffbaSStephan Aßmus src += bpr;
25873a2ffbaSStephan Aßmus dst += bpr;
25973a2ffbaSStephan Aßmus }
26073a2ffbaSStephan Aßmus break;
26173a2ffbaSStephan Aßmus
26273a2ffbaSStephan Aßmus case MODE_MULTIPLY_ALPHA:
26373a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
26473a2ffbaSStephan Aßmus uint8* srcHandle = src;
26573a2ffbaSStephan Aßmus uint8* dstHandle = dst;
26673a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
26773a2ffbaSStephan Aßmus // compose
26873a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], srcHandle[3]);
26936947c7bSOliver Tappe dstHandle[3] = (
27036947c7bSOliver Tappe dstHandle[3] * (255 - alphaOverride)
27136947c7bSOliver Tappe + temp * alphaOverride
27236947c7bSOliver Tappe ) / 255;
27373a2ffbaSStephan Aßmus srcHandle += 4;
27473a2ffbaSStephan Aßmus dstHandle += 4;
27573a2ffbaSStephan Aßmus }
27673a2ffbaSStephan Aßmus src += bpr;
27773a2ffbaSStephan Aßmus dst += bpr;
27873a2ffbaSStephan Aßmus }
27973a2ffbaSStephan Aßmus break;
28073a2ffbaSStephan Aßmus
28173a2ffbaSStephan Aßmus case MODE_LUMINANCE:
28273a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
28373a2ffbaSStephan Aßmus uint8* srcHandle = src;
28473a2ffbaSStephan Aßmus uint8* dstHandle = dst;
28573a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
28673a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
28773a2ffbaSStephan Aßmus // compose
28873a2ffbaSStephan Aßmus uint8 r = dstHandle[2];
28973a2ffbaSStephan Aßmus uint8 g = dstHandle[1];
29073a2ffbaSStephan Aßmus uint8 b = dstHandle[0];
29173a2ffbaSStephan Aßmus uint8 alpha = dstHandle[3];
29236947c7bSOliver Tappe replace_luminance(r, g, b, srcHandle[2], srcHandle[1],
29336947c7bSOliver Tappe srcHandle[0]);
29436947c7bSOliver Tappe blend_colors(dstHandle,
29536947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, b, g, r);
29673a2ffbaSStephan Aßmus dstHandle[3] = alpha;
29773a2ffbaSStephan Aßmus }
29873a2ffbaSStephan Aßmus srcHandle += 4;
29973a2ffbaSStephan Aßmus dstHandle += 4;
30073a2ffbaSStephan Aßmus }
30173a2ffbaSStephan Aßmus src += bpr;
30273a2ffbaSStephan Aßmus dst += bpr;
30373a2ffbaSStephan Aßmus }
30473a2ffbaSStephan Aßmus break;
30573a2ffbaSStephan Aßmus
30673a2ffbaSStephan Aßmus case MODE_INVERSE_MULTIPLY:
30773a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
30873a2ffbaSStephan Aßmus uint8* srcHandle = src;
30973a2ffbaSStephan Aßmus uint8* dstHandle = dst;
31073a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
31173a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
31273a2ffbaSStephan Aßmus // compose
31336947c7bSOliver Tappe uint8 c1 = 255 - (
31436947c7bSOliver Tappe (((255 - srcHandle[0]) * (255 - dstHandle[0]))
31536947c7bSOliver Tappe / 255) * dstHandle[3]
31636947c7bSOliver Tappe + (255 - srcHandle[0]) * (255 - dstHandle[3])
31736947c7bSOliver Tappe ) / 255;
31836947c7bSOliver Tappe uint8 c2 = 255 - (
31936947c7bSOliver Tappe (((255 - srcHandle[1]) * (255 - dstHandle[1]))
32036947c7bSOliver Tappe / 255) * dstHandle[3]
32136947c7bSOliver Tappe + (255 - srcHandle[1]) * (255 - dstHandle[3])
32236947c7bSOliver Tappe ) / 255;
32336947c7bSOliver Tappe uint8 c3 = 255 - (
32436947c7bSOliver Tappe (((255 - srcHandle[2]) * (255 - dstHandle[2]))
32536947c7bSOliver Tappe / 255) * dstHandle[3]
32636947c7bSOliver Tappe + (255 - srcHandle[2]) * (255 - dstHandle[3])
32736947c7bSOliver Tappe ) / 255;
32836947c7bSOliver Tappe blend_colors(dstHandle,
32936947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3);
33073a2ffbaSStephan Aßmus }
33173a2ffbaSStephan Aßmus srcHandle += 4;
33273a2ffbaSStephan Aßmus dstHandle += 4;
33373a2ffbaSStephan Aßmus }
33473a2ffbaSStephan Aßmus src += bpr;
33573a2ffbaSStephan Aßmus dst += bpr;
33673a2ffbaSStephan Aßmus }
33773a2ffbaSStephan Aßmus break;
33873a2ffbaSStephan Aßmus
33973a2ffbaSStephan Aßmus case MODE_MULTIPLY:
34073a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
34173a2ffbaSStephan Aßmus uint8* srcHandle = src;
34273a2ffbaSStephan Aßmus uint8* dstHandle = dst;
34373a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
34473a2ffbaSStephan Aßmus if (srcHandle[3] > 0) {
34573a2ffbaSStephan Aßmus // compose
34636947c7bSOliver Tappe uint8 c1 = (
34736947c7bSOliver Tappe ((srcHandle[0] * dstHandle[0]) / 255)
34836947c7bSOliver Tappe * dstHandle[3]
34936947c7bSOliver Tappe + srcHandle[0] * (255 - dstHandle[3])
35036947c7bSOliver Tappe ) / 255;
35136947c7bSOliver Tappe uint8 c2 = (
35236947c7bSOliver Tappe ((srcHandle[1] * dstHandle[1]) / 255)
35336947c7bSOliver Tappe * dstHandle[3]
35436947c7bSOliver Tappe + srcHandle[1] * (255 - dstHandle[3])
35536947c7bSOliver Tappe ) / 255;
35636947c7bSOliver Tappe uint8 c3 = (
35736947c7bSOliver Tappe ((srcHandle[2] * dstHandle[2]) / 255)
35836947c7bSOliver Tappe * dstHandle[3]
35936947c7bSOliver Tappe + srcHandle[2] * (255 - dstHandle[3])
36036947c7bSOliver Tappe ) / 255;
36136947c7bSOliver Tappe blend_colors(dstHandle,
36236947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3);
36373a2ffbaSStephan Aßmus }
36473a2ffbaSStephan Aßmus srcHandle += 4;
36573a2ffbaSStephan Aßmus dstHandle += 4;
36673a2ffbaSStephan Aßmus }
36773a2ffbaSStephan Aßmus src += bpr;
36873a2ffbaSStephan Aßmus dst += bpr;
36973a2ffbaSStephan Aßmus }
37073a2ffbaSStephan Aßmus break;
37173a2ffbaSStephan Aßmus
37273a2ffbaSStephan Aßmus case MODE_NORMAL:
37373a2ffbaSStephan Aßmus default:
37473a2ffbaSStephan Aßmus if (alphaOverride == 255) {
37573a2ffbaSStephan Aßmus // use an optimized version that composes the bitmaps directly
37673a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
37773a2ffbaSStephan Aßmus uint8* srcHandle = src;
37873a2ffbaSStephan Aßmus uint8* dstHandle = dst;
37973a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
38073a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle);
38173a2ffbaSStephan Aßmus srcHandle += 4;
38273a2ffbaSStephan Aßmus dstHandle += 4;
38373a2ffbaSStephan Aßmus }
38473a2ffbaSStephan Aßmus src += bpr;
38573a2ffbaSStephan Aßmus dst += bpr;
38673a2ffbaSStephan Aßmus }
38773a2ffbaSStephan Aßmus } else {
38873a2ffbaSStephan Aßmus for (; top <= bottom; top++) {
38973a2ffbaSStephan Aßmus uint8* srcHandle = src;
39073a2ffbaSStephan Aßmus uint8* dstHandle = dst;
39173a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) {
39273a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle, alphaOverride);
39373a2ffbaSStephan Aßmus srcHandle += 4;
39473a2ffbaSStephan Aßmus dstHandle += 4;
39573a2ffbaSStephan Aßmus }
39673a2ffbaSStephan Aßmus src += bpr;
39773a2ffbaSStephan Aßmus dst += bpr;
39873a2ffbaSStephan Aßmus }
39973a2ffbaSStephan Aßmus }
40073a2ffbaSStephan Aßmus break;
40173a2ffbaSStephan Aßmus }
40273a2ffbaSStephan Aßmus
40373a2ffbaSStephan Aßmus return status;
40473a2ffbaSStephan Aßmus }
40573a2ffbaSStephan Aßmus
40636947c7bSOliver Tappe
40773a2ffbaSStephan Aßmus // Unarchive
40873a2ffbaSStephan Aßmus status_t
Unarchive(const BMessage * archive)40973a2ffbaSStephan Aßmus Layer::Unarchive(const BMessage* archive)
41073a2ffbaSStephan Aßmus {
41173a2ffbaSStephan Aßmus if (!archive)
41273a2ffbaSStephan Aßmus return B_BAD_VALUE;
41373a2ffbaSStephan Aßmus
41473a2ffbaSStephan Aßmus // restore attributes
41573a2ffbaSStephan Aßmus float alpha;
41673a2ffbaSStephan Aßmus if (archive->FindFloat("alpha", &alpha) == B_OK) {
41773a2ffbaSStephan Aßmus constrain(alpha, 0.0, 1.0);
41873a2ffbaSStephan Aßmus fAlpha = alpha;
41973a2ffbaSStephan Aßmus } else
42073a2ffbaSStephan Aßmus fAlpha = 1.0;
42173a2ffbaSStephan Aßmus if (archive->FindInt32("mode", (int32*)&fMode) < B_OK)
42273a2ffbaSStephan Aßmus fMode = MODE_NORMAL;
42373a2ffbaSStephan Aßmus if (archive->FindInt32("flags", (int32*)&fFlags) < B_OK)
42473a2ffbaSStephan Aßmus fFlags = 0;
42573a2ffbaSStephan Aßmus
42673a2ffbaSStephan Aßmus // delete current contents
42773a2ffbaSStephan Aßmus delete fBitmap;
42873a2ffbaSStephan Aßmus fBitmap = NULL;
42973a2ffbaSStephan Aßmus
43073a2ffbaSStephan Aßmus status_t status = extract_bitmap(&fBitmap, archive, "current bitmap");
43173a2ffbaSStephan Aßmus if (status < B_OK)
43273a2ffbaSStephan Aßmus return status;
43373a2ffbaSStephan Aßmus
43473a2ffbaSStephan Aßmus // "bounds" is where the layer actually has content
43573a2ffbaSStephan Aßmus BRect bounds;
43673a2ffbaSStephan Aßmus if (archive->FindRect("bounds", &bounds) == B_OK)
43773a2ffbaSStephan Aßmus fBounds = bounds;
43873a2ffbaSStephan Aßmus else
43973a2ffbaSStephan Aßmus fBounds.Set(0.0, 0.0, -1.0, -1.0);
44073a2ffbaSStephan Aßmus
44173a2ffbaSStephan Aßmus // validate status of fBitmap
44273a2ffbaSStephan Aßmus if (!fBitmap)
44373a2ffbaSStephan Aßmus return B_ERROR;
44473a2ffbaSStephan Aßmus
44573a2ffbaSStephan Aßmus status = fBitmap->InitCheck();
44673a2ffbaSStephan Aßmus if (status < B_OK) {
44773a2ffbaSStephan Aßmus delete fBitmap;
44873a2ffbaSStephan Aßmus fBitmap = NULL;
44973a2ffbaSStephan Aßmus }
45073a2ffbaSStephan Aßmus
45173a2ffbaSStephan Aßmus return status;
45273a2ffbaSStephan Aßmus }
453