1*73a2ffbaSStephan Aßmus /* 2*73a2ffbaSStephan Aßmus * Copyright 2006, Haiku. All rights reserved. 3*73a2ffbaSStephan Aßmus * Distributed under the terms of the MIT License. 4*73a2ffbaSStephan Aßmus * 5*73a2ffbaSStephan Aßmus * Authors: 6*73a2ffbaSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 7*73a2ffbaSStephan Aßmus */ 8*73a2ffbaSStephan Aßmus 9*73a2ffbaSStephan Aßmus #include "Layer.h" 10*73a2ffbaSStephan Aßmus 11*73a2ffbaSStephan Aßmus #include <stdio.h> 12*73a2ffbaSStephan Aßmus 13*73a2ffbaSStephan Aßmus #include <Bitmap.h> 14*73a2ffbaSStephan Aßmus #include <Message.h> 15*73a2ffbaSStephan Aßmus 16*73a2ffbaSStephan Aßmus #include "bitmap_compression.h" 17*73a2ffbaSStephan Aßmus #include "blending.h" 18*73a2ffbaSStephan Aßmus #include "lab_convert.h" 19*73a2ffbaSStephan Aßmus #include "support.h" 20*73a2ffbaSStephan Aßmus 21*73a2ffbaSStephan Aßmus // constructor 22*73a2ffbaSStephan Aßmus Layer::Layer() 23*73a2ffbaSStephan Aßmus : fBitmap(NULL), 24*73a2ffbaSStephan Aßmus fBounds(0.0, 0.0, -1.0, -1.0), 25*73a2ffbaSStephan Aßmus fAlpha(1.0), 26*73a2ffbaSStephan Aßmus fMode(MODE_NORMAL), 27*73a2ffbaSStephan Aßmus fFlags(0) 28*73a2ffbaSStephan Aßmus { 29*73a2ffbaSStephan Aßmus } 30*73a2ffbaSStephan Aßmus 31*73a2ffbaSStephan Aßmus // destructor 32*73a2ffbaSStephan Aßmus Layer::~Layer() 33*73a2ffbaSStephan Aßmus { 34*73a2ffbaSStephan Aßmus delete fBitmap; 35*73a2ffbaSStephan Aßmus } 36*73a2ffbaSStephan Aßmus 37*73a2ffbaSStephan Aßmus // Compose 38*73a2ffbaSStephan Aßmus status_t 39*73a2ffbaSStephan Aßmus Layer::Compose(const BBitmap* into, BRect area) 40*73a2ffbaSStephan Aßmus { 41*73a2ffbaSStephan Aßmus if (!fBitmap || !fBitmap->IsValid() 42*73a2ffbaSStephan Aßmus || (fBitmap->ColorSpace() != B_RGBA32 && fBitmap->ColorSpace() != B_RGB32)) 43*73a2ffbaSStephan Aßmus return B_NO_INIT; 44*73a2ffbaSStephan Aßmus 45*73a2ffbaSStephan Aßmus status_t status = B_BAD_VALUE; 46*73a2ffbaSStephan Aßmus if (!into || !area.IsValid() || (status = into->InitCheck()) < B_OK) 47*73a2ffbaSStephan Aßmus return status; 48*73a2ffbaSStephan Aßmus 49*73a2ffbaSStephan Aßmus // make sure we don't access memory outside of our bitmap 50*73a2ffbaSStephan Aßmus area = area & fBitmap->Bounds(); 51*73a2ffbaSStephan Aßmus 52*73a2ffbaSStephan Aßmus BRect r = ActiveBounds(); 53*73a2ffbaSStephan Aßmus if (!r.IsValid() || (fFlags & FLAG_INVISIBLE) || !r.Intersects(area)) 54*73a2ffbaSStephan Aßmus return B_OK; 55*73a2ffbaSStephan Aßmus 56*73a2ffbaSStephan Aßmus r = r & area; 57*73a2ffbaSStephan Aßmus int32 left, top, right, bottom; 58*73a2ffbaSStephan Aßmus rect_to_int(r, left, top, right, bottom); 59*73a2ffbaSStephan Aßmus 60*73a2ffbaSStephan Aßmus uint8* src = (uint8*)fBitmap->Bits(); 61*73a2ffbaSStephan Aßmus uint8* dst = (uint8*)into->Bits(); 62*73a2ffbaSStephan Aßmus uint32 bpr = into->BytesPerRow(); 63*73a2ffbaSStephan Aßmus src += 4 * left + bpr * top; 64*73a2ffbaSStephan Aßmus dst += 4 * left + bpr * top; 65*73a2ffbaSStephan Aßmus uint8 alphaOverride = (uint8)(fAlpha * 255); 66*73a2ffbaSStephan Aßmus 67*73a2ffbaSStephan Aßmus switch (fMode) { 68*73a2ffbaSStephan Aßmus 69*73a2ffbaSStephan Aßmus case MODE_SOFT_LIGHT: 70*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 71*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 72*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 73*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 74*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 75*73a2ffbaSStephan Aßmus uint8 c1 = dstHandle[0] * srcHandle[0] >> 8; 76*73a2ffbaSStephan Aßmus c1 = c1 + dstHandle[0] * (255 - ((255 - dstHandle[0]) * (255 - srcHandle[0]) >> 8) - c1) >> 8; 77*73a2ffbaSStephan Aßmus c1 = (c1 * dstHandle[3] + srcHandle[0] * (255 - dstHandle[3])) >> 8; 78*73a2ffbaSStephan Aßmus 79*73a2ffbaSStephan Aßmus uint8 c2 = dstHandle[1] * srcHandle[1] >> 8; 80*73a2ffbaSStephan Aßmus c2 = c2 + dstHandle[1] * (255 - ((255 - dstHandle[1]) * (255 - srcHandle[1]) >> 8) - c2) >> 8; 81*73a2ffbaSStephan Aßmus c2 = (c2 * dstHandle[3] + srcHandle[1] * (255 - dstHandle[3])) >> 8; 82*73a2ffbaSStephan Aßmus 83*73a2ffbaSStephan Aßmus uint8 c3 = dstHandle[2] * srcHandle[2] >> 8; 84*73a2ffbaSStephan Aßmus c3 = c3 + dstHandle[2] * (255 - ((255 - dstHandle[2]) * (255 - srcHandle[2]) >> 8) - c3) >> 8; 85*73a2ffbaSStephan Aßmus c3 = (c3 * dstHandle[3] + srcHandle[2] * (255 - dstHandle[3])) >> 8; 86*73a2ffbaSStephan Aßmus 87*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) >> 8, 88*73a2ffbaSStephan Aßmus c1, c2, c3); 89*73a2ffbaSStephan Aßmus } 90*73a2ffbaSStephan Aßmus srcHandle += 4; 91*73a2ffbaSStephan Aßmus dstHandle += 4; 92*73a2ffbaSStephan Aßmus } 93*73a2ffbaSStephan Aßmus src += bpr; 94*73a2ffbaSStephan Aßmus dst += bpr; 95*73a2ffbaSStephan Aßmus } 96*73a2ffbaSStephan Aßmus break; 97*73a2ffbaSStephan Aßmus 98*73a2ffbaSStephan Aßmus case MODE_LIGHTEN: 99*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 100*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 101*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 102*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 103*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 104*73a2ffbaSStephan Aßmus // compose 105*73a2ffbaSStephan Aßmus uint8 c1 = (max_c(srcHandle[0], dstHandle[0]) * dstHandle[3] 106*73a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255; 107*73a2ffbaSStephan Aßmus uint8 c2 = (max_c(srcHandle[1], dstHandle[1]) * dstHandle[3] 108*73a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255; 109*73a2ffbaSStephan Aßmus uint8 c3 = (max_c(srcHandle[2], dstHandle[2]) * dstHandle[3] 110*73a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255; 111*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) / 255, 112*73a2ffbaSStephan Aßmus c1, c2, c3); 113*73a2ffbaSStephan Aßmus } 114*73a2ffbaSStephan Aßmus srcHandle += 4; 115*73a2ffbaSStephan Aßmus dstHandle += 4; 116*73a2ffbaSStephan Aßmus } 117*73a2ffbaSStephan Aßmus src += bpr; 118*73a2ffbaSStephan Aßmus dst += bpr; 119*73a2ffbaSStephan Aßmus } 120*73a2ffbaSStephan Aßmus break; 121*73a2ffbaSStephan Aßmus 122*73a2ffbaSStephan Aßmus case MODE_DARKEN: 123*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 124*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 125*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 126*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 127*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 128*73a2ffbaSStephan Aßmus // compose 129*73a2ffbaSStephan Aßmus uint8 c1 = (min_c(srcHandle[0], dstHandle[0]) * dstHandle[3] 130*73a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255; 131*73a2ffbaSStephan Aßmus uint8 c2 = (min_c(srcHandle[1], dstHandle[1]) * dstHandle[3] 132*73a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255; 133*73a2ffbaSStephan Aßmus uint8 c3 = (min_c(srcHandle[2], dstHandle[2]) * dstHandle[3] 134*73a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255; 135*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) / 255, 136*73a2ffbaSStephan Aßmus c1, c2, c3); 137*73a2ffbaSStephan Aßmus } 138*73a2ffbaSStephan Aßmus srcHandle += 4; 139*73a2ffbaSStephan Aßmus dstHandle += 4; 140*73a2ffbaSStephan Aßmus } 141*73a2ffbaSStephan Aßmus src += bpr; 142*73a2ffbaSStephan Aßmus dst += bpr; 143*73a2ffbaSStephan Aßmus } 144*73a2ffbaSStephan Aßmus break; 145*73a2ffbaSStephan Aßmus 146*73a2ffbaSStephan Aßmus case MODE_REPLACE_RED: 147*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 148*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 149*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 150*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 151*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 152*73a2ffbaSStephan Aßmus // compose 153*73a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 154*73a2ffbaSStephan Aßmus dstHandle[2] = (srcHandle[2] * alpha 155*73a2ffbaSStephan Aßmus + dstHandle[2] * (65025 - alpha)) / 65025; 156*73a2ffbaSStephan Aßmus } 157*73a2ffbaSStephan Aßmus srcHandle += 4; 158*73a2ffbaSStephan Aßmus dstHandle += 4; 159*73a2ffbaSStephan Aßmus } 160*73a2ffbaSStephan Aßmus src += bpr; 161*73a2ffbaSStephan Aßmus dst += bpr; 162*73a2ffbaSStephan Aßmus } 163*73a2ffbaSStephan Aßmus break; 164*73a2ffbaSStephan Aßmus 165*73a2ffbaSStephan Aßmus case MODE_REPLACE_GREEN: 166*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 167*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 168*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 169*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 170*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 171*73a2ffbaSStephan Aßmus // compose 172*73a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 173*73a2ffbaSStephan Aßmus dstHandle[1] = (srcHandle[1] * alpha 174*73a2ffbaSStephan Aßmus + dstHandle[1] * (65025 - alpha)) / 65025; 175*73a2ffbaSStephan Aßmus } 176*73a2ffbaSStephan Aßmus srcHandle += 4; 177*73a2ffbaSStephan Aßmus dstHandle += 4; 178*73a2ffbaSStephan Aßmus } 179*73a2ffbaSStephan Aßmus src += bpr; 180*73a2ffbaSStephan Aßmus dst += bpr; 181*73a2ffbaSStephan Aßmus } 182*73a2ffbaSStephan Aßmus break; 183*73a2ffbaSStephan Aßmus 184*73a2ffbaSStephan Aßmus case MODE_REPLACE_BLUE: 185*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 186*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 187*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 188*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 189*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 190*73a2ffbaSStephan Aßmus // compose 191*73a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 192*73a2ffbaSStephan Aßmus dstHandle[0] = (srcHandle[0] * alpha 193*73a2ffbaSStephan Aßmus + dstHandle[0] * (65025 - alpha)) / 65025; 194*73a2ffbaSStephan Aßmus } 195*73a2ffbaSStephan Aßmus srcHandle += 4; 196*73a2ffbaSStephan Aßmus dstHandle += 4; 197*73a2ffbaSStephan Aßmus } 198*73a2ffbaSStephan Aßmus src += bpr; 199*73a2ffbaSStephan Aßmus dst += bpr; 200*73a2ffbaSStephan Aßmus } 201*73a2ffbaSStephan Aßmus break; 202*73a2ffbaSStephan Aßmus 203*73a2ffbaSStephan Aßmus case MODE_MULTIPLY_INVERSE_ALPHA: 204*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 205*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 206*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 207*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 208*73a2ffbaSStephan Aßmus // compose 209*73a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], 255 - srcHandle[3]); 210*73a2ffbaSStephan Aßmus dstHandle[3] = (dstHandle[3] * (255 - alphaOverride) + temp * alphaOverride) / 255; 211*73a2ffbaSStephan Aßmus srcHandle += 4; 212*73a2ffbaSStephan Aßmus dstHandle += 4; 213*73a2ffbaSStephan Aßmus } 214*73a2ffbaSStephan Aßmus src += bpr; 215*73a2ffbaSStephan Aßmus dst += bpr; 216*73a2ffbaSStephan Aßmus } 217*73a2ffbaSStephan Aßmus break; 218*73a2ffbaSStephan Aßmus 219*73a2ffbaSStephan Aßmus case MODE_MULTIPLY_ALPHA: 220*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 221*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 222*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 223*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 224*73a2ffbaSStephan Aßmus // compose 225*73a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], srcHandle[3]); 226*73a2ffbaSStephan Aßmus dstHandle[3] = (dstHandle[3] * (255 - alphaOverride) + temp * alphaOverride) / 255; 227*73a2ffbaSStephan Aßmus srcHandle += 4; 228*73a2ffbaSStephan Aßmus dstHandle += 4; 229*73a2ffbaSStephan Aßmus } 230*73a2ffbaSStephan Aßmus src += bpr; 231*73a2ffbaSStephan Aßmus dst += bpr; 232*73a2ffbaSStephan Aßmus } 233*73a2ffbaSStephan Aßmus break; 234*73a2ffbaSStephan Aßmus 235*73a2ffbaSStephan Aßmus case MODE_LUMINANCE: 236*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 237*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 238*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 239*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 240*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 241*73a2ffbaSStephan Aßmus // compose 242*73a2ffbaSStephan Aßmus uint8 r = dstHandle[2]; 243*73a2ffbaSStephan Aßmus uint8 g = dstHandle[1]; 244*73a2ffbaSStephan Aßmus uint8 b = dstHandle[0]; 245*73a2ffbaSStephan Aßmus uint8 alpha = dstHandle[3]; 246*73a2ffbaSStephan Aßmus replace_luminance(r, g, b, srcHandle[2], srcHandle[1], srcHandle[0]); 247*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) / 255, 248*73a2ffbaSStephan Aßmus b, g, r); 249*73a2ffbaSStephan Aßmus dstHandle[3] = alpha; 250*73a2ffbaSStephan Aßmus } 251*73a2ffbaSStephan Aßmus srcHandle += 4; 252*73a2ffbaSStephan Aßmus dstHandle += 4; 253*73a2ffbaSStephan Aßmus } 254*73a2ffbaSStephan Aßmus src += bpr; 255*73a2ffbaSStephan Aßmus dst += bpr; 256*73a2ffbaSStephan Aßmus } 257*73a2ffbaSStephan Aßmus break; 258*73a2ffbaSStephan Aßmus 259*73a2ffbaSStephan Aßmus case MODE_INVERSE_MULTIPLY: 260*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 261*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 262*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 263*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 264*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 265*73a2ffbaSStephan Aßmus // compose 266*73a2ffbaSStephan Aßmus uint8 c1 = 255 - ((((255 - srcHandle[0]) * (255 - dstHandle[0])) / 255) * dstHandle[3] 267*73a2ffbaSStephan Aßmus + (255 - srcHandle[0]) * (255 - dstHandle[3])) / 255; 268*73a2ffbaSStephan Aßmus uint8 c2 = 255 - ((((255 - srcHandle[1]) * (255 - dstHandle[1])) / 255) * dstHandle[3] 269*73a2ffbaSStephan Aßmus + (255 - srcHandle[1]) * (255 - dstHandle[3])) / 255; 270*73a2ffbaSStephan Aßmus uint8 c3 = 255 - ((((255 - srcHandle[2]) * (255 - dstHandle[2])) / 255) * dstHandle[3] 271*73a2ffbaSStephan Aßmus + (255 - srcHandle[2]) * (255 - dstHandle[3])) / 255; 272*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) / 255, 273*73a2ffbaSStephan Aßmus c1, c2, c3); 274*73a2ffbaSStephan Aßmus } 275*73a2ffbaSStephan Aßmus srcHandle += 4; 276*73a2ffbaSStephan Aßmus dstHandle += 4; 277*73a2ffbaSStephan Aßmus } 278*73a2ffbaSStephan Aßmus src += bpr; 279*73a2ffbaSStephan Aßmus dst += bpr; 280*73a2ffbaSStephan Aßmus } 281*73a2ffbaSStephan Aßmus break; 282*73a2ffbaSStephan Aßmus 283*73a2ffbaSStephan Aßmus case MODE_MULTIPLY: 284*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 285*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 286*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 287*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 288*73a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 289*73a2ffbaSStephan Aßmus // compose 290*73a2ffbaSStephan Aßmus uint8 c1 = (((srcHandle[0] * dstHandle[0]) / 255) * dstHandle[3] 291*73a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255; 292*73a2ffbaSStephan Aßmus uint8 c2 = (((srcHandle[1] * dstHandle[1]) / 255) * dstHandle[3] 293*73a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255; 294*73a2ffbaSStephan Aßmus uint8 c3 = (((srcHandle[2] * dstHandle[2]) / 255) * dstHandle[3] 295*73a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255; 296*73a2ffbaSStephan Aßmus blend_colors(dstHandle, (srcHandle[3] * alphaOverride) / 255, 297*73a2ffbaSStephan Aßmus c1, c2, c3); 298*73a2ffbaSStephan Aßmus } 299*73a2ffbaSStephan Aßmus srcHandle += 4; 300*73a2ffbaSStephan Aßmus dstHandle += 4; 301*73a2ffbaSStephan Aßmus } 302*73a2ffbaSStephan Aßmus src += bpr; 303*73a2ffbaSStephan Aßmus dst += bpr; 304*73a2ffbaSStephan Aßmus } 305*73a2ffbaSStephan Aßmus break; 306*73a2ffbaSStephan Aßmus 307*73a2ffbaSStephan Aßmus case MODE_NORMAL: 308*73a2ffbaSStephan Aßmus default: 309*73a2ffbaSStephan Aßmus if (alphaOverride == 255) { 310*73a2ffbaSStephan Aßmus // use an optimized version that composes the bitmaps directly 311*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 312*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 313*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 314*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 315*73a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle); 316*73a2ffbaSStephan Aßmus srcHandle += 4; 317*73a2ffbaSStephan Aßmus dstHandle += 4; 318*73a2ffbaSStephan Aßmus } 319*73a2ffbaSStephan Aßmus src += bpr; 320*73a2ffbaSStephan Aßmus dst += bpr; 321*73a2ffbaSStephan Aßmus } 322*73a2ffbaSStephan Aßmus } else { 323*73a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 324*73a2ffbaSStephan Aßmus uint8* srcHandle = src; 325*73a2ffbaSStephan Aßmus uint8* dstHandle = dst; 326*73a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 327*73a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle, alphaOverride); 328*73a2ffbaSStephan Aßmus srcHandle += 4; 329*73a2ffbaSStephan Aßmus dstHandle += 4; 330*73a2ffbaSStephan Aßmus } 331*73a2ffbaSStephan Aßmus src += bpr; 332*73a2ffbaSStephan Aßmus dst += bpr; 333*73a2ffbaSStephan Aßmus } 334*73a2ffbaSStephan Aßmus } 335*73a2ffbaSStephan Aßmus break; 336*73a2ffbaSStephan Aßmus } 337*73a2ffbaSStephan Aßmus 338*73a2ffbaSStephan Aßmus return status; 339*73a2ffbaSStephan Aßmus } 340*73a2ffbaSStephan Aßmus 341*73a2ffbaSStephan Aßmus // Unarchive 342*73a2ffbaSStephan Aßmus status_t 343*73a2ffbaSStephan Aßmus Layer::Unarchive(const BMessage* archive) 344*73a2ffbaSStephan Aßmus { 345*73a2ffbaSStephan Aßmus if (!archive) 346*73a2ffbaSStephan Aßmus return B_BAD_VALUE; 347*73a2ffbaSStephan Aßmus 348*73a2ffbaSStephan Aßmus // restore attributes 349*73a2ffbaSStephan Aßmus float alpha; 350*73a2ffbaSStephan Aßmus if (archive->FindFloat("alpha", &alpha) == B_OK) { 351*73a2ffbaSStephan Aßmus constrain(alpha, 0.0, 1.0); 352*73a2ffbaSStephan Aßmus fAlpha = alpha; 353*73a2ffbaSStephan Aßmus } else 354*73a2ffbaSStephan Aßmus fAlpha = 1.0; 355*73a2ffbaSStephan Aßmus if (archive->FindInt32("mode", (int32*)&fMode) < B_OK) 356*73a2ffbaSStephan Aßmus fMode = MODE_NORMAL; 357*73a2ffbaSStephan Aßmus if (archive->FindInt32("flags", (int32*)&fFlags) < B_OK) 358*73a2ffbaSStephan Aßmus fFlags = 0; 359*73a2ffbaSStephan Aßmus 360*73a2ffbaSStephan Aßmus // delete current contents 361*73a2ffbaSStephan Aßmus delete fBitmap; 362*73a2ffbaSStephan Aßmus fBitmap = NULL; 363*73a2ffbaSStephan Aßmus 364*73a2ffbaSStephan Aßmus status_t status = extract_bitmap(&fBitmap, archive, "current bitmap"); 365*73a2ffbaSStephan Aßmus if (status < B_OK) 366*73a2ffbaSStephan Aßmus return status; 367*73a2ffbaSStephan Aßmus 368*73a2ffbaSStephan Aßmus // "bounds" is where the layer actually has content 369*73a2ffbaSStephan Aßmus BRect bounds; 370*73a2ffbaSStephan Aßmus if (archive->FindRect("bounds", &bounds) == B_OK) 371*73a2ffbaSStephan Aßmus fBounds = bounds; 372*73a2ffbaSStephan Aßmus else 373*73a2ffbaSStephan Aßmus fBounds.Set(0.0, 0.0, -1.0, -1.0); 374*73a2ffbaSStephan Aßmus 375*73a2ffbaSStephan Aßmus // validate status of fBitmap 376*73a2ffbaSStephan Aßmus if (!fBitmap) 377*73a2ffbaSStephan Aßmus return B_ERROR; 378*73a2ffbaSStephan Aßmus 379*73a2ffbaSStephan Aßmus status = fBitmap->InitCheck(); 380*73a2ffbaSStephan Aßmus if (status < B_OK) { 381*73a2ffbaSStephan Aßmus delete fBitmap; 382*73a2ffbaSStephan Aßmus fBitmap = NULL; 383*73a2ffbaSStephan Aßmus } 384*73a2ffbaSStephan Aßmus 385*73a2ffbaSStephan Aßmus return status; 386*73a2ffbaSStephan Aßmus } 387