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> 1573a2ffbaSStephan Aßmus #include <Message.h> 1673a2ffbaSStephan Aßmus 1773a2ffbaSStephan Aßmus #include "bitmap_compression.h" 1873a2ffbaSStephan Aßmus #include "blending.h" 1973a2ffbaSStephan Aßmus #include "lab_convert.h" 2073a2ffbaSStephan Aßmus #include "support.h" 2173a2ffbaSStephan Aßmus 2236947c7bSOliver Tappe 2373a2ffbaSStephan Aßmus // constructor 2473a2ffbaSStephan Aßmus Layer::Layer() 2573a2ffbaSStephan Aßmus : fBitmap(NULL), 2673a2ffbaSStephan Aßmus fBounds(0.0, 0.0, -1.0, -1.0), 2773a2ffbaSStephan Aßmus fAlpha(1.0), 2873a2ffbaSStephan Aßmus fMode(MODE_NORMAL), 2973a2ffbaSStephan Aßmus fFlags(0) 3073a2ffbaSStephan Aßmus { 3173a2ffbaSStephan Aßmus } 3273a2ffbaSStephan Aßmus 3336947c7bSOliver Tappe 3473a2ffbaSStephan Aßmus // destructor 3573a2ffbaSStephan Aßmus Layer::~Layer() 3673a2ffbaSStephan Aßmus { 3773a2ffbaSStephan Aßmus delete fBitmap; 3873a2ffbaSStephan Aßmus } 3973a2ffbaSStephan Aßmus 4036947c7bSOliver Tappe 4173a2ffbaSStephan Aßmus // Compose 4273a2ffbaSStephan Aßmus status_t 4373a2ffbaSStephan Aßmus Layer::Compose(const BBitmap* into, BRect area) 4473a2ffbaSStephan Aßmus { 4573a2ffbaSStephan Aßmus if (!fBitmap || !fBitmap->IsValid() 4636947c7bSOliver Tappe || (fBitmap->ColorSpace() != B_RGBA32 4736947c7bSOliver Tappe && fBitmap->ColorSpace() != B_RGB32)) 4873a2ffbaSStephan Aßmus return B_NO_INIT; 4973a2ffbaSStephan Aßmus 5073a2ffbaSStephan Aßmus status_t status = B_BAD_VALUE; 5173a2ffbaSStephan Aßmus if (!into || !area.IsValid() || (status = into->InitCheck()) < B_OK) 5273a2ffbaSStephan Aßmus return status; 5373a2ffbaSStephan Aßmus 5473a2ffbaSStephan Aßmus // make sure we don't access memory outside of our bitmap 5573a2ffbaSStephan Aßmus area = area & fBitmap->Bounds(); 5673a2ffbaSStephan Aßmus 5773a2ffbaSStephan Aßmus BRect r = ActiveBounds(); 5873a2ffbaSStephan Aßmus if (!r.IsValid() || (fFlags & FLAG_INVISIBLE) || !r.Intersects(area)) 5973a2ffbaSStephan Aßmus return B_OK; 6073a2ffbaSStephan Aßmus 6173a2ffbaSStephan Aßmus r = r & area; 6273a2ffbaSStephan Aßmus int32 left, top, right, bottom; 6373a2ffbaSStephan Aßmus rect_to_int(r, left, top, right, bottom); 6473a2ffbaSStephan Aßmus 6573a2ffbaSStephan Aßmus uint8* src = (uint8*)fBitmap->Bits(); 6673a2ffbaSStephan Aßmus uint8* dst = (uint8*)into->Bits(); 6773a2ffbaSStephan Aßmus uint32 bpr = into->BytesPerRow(); 6873a2ffbaSStephan Aßmus src += 4 * left + bpr * top; 6973a2ffbaSStephan Aßmus dst += 4 * left + bpr * top; 7073a2ffbaSStephan Aßmus uint8 alphaOverride = (uint8)(fAlpha * 255); 7173a2ffbaSStephan Aßmus 7273a2ffbaSStephan Aßmus switch (fMode) { 7373a2ffbaSStephan Aßmus 7473a2ffbaSStephan Aßmus case MODE_SOFT_LIGHT: 7573a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 7673a2ffbaSStephan Aßmus uint8* srcHandle = src; 7773a2ffbaSStephan Aßmus uint8* dstHandle = dst; 7873a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 7973a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 8073a2ffbaSStephan Aßmus uint8 c1 = dstHandle[0] * srcHandle[0] >> 8; 81*258b762aSOliver Tappe c1 += dstHandle[0] * ( 8236947c7bSOliver Tappe 255 - ( 8336947c7bSOliver Tappe (255 - dstHandle[0]) 8436947c7bSOliver Tappe * (255 - srcHandle[0]) 8536947c7bSOliver Tappe >> 8 8636947c7bSOliver Tappe ) - c1 8736947c7bSOliver Tappe ) >> 8; 8836947c7bSOliver Tappe c1 = (c1 * dstHandle[3] 8936947c7bSOliver Tappe + srcHandle[0] * (255 - dstHandle[3]) 9036947c7bSOliver Tappe ) >> 8; 9173a2ffbaSStephan Aßmus 9273a2ffbaSStephan Aßmus uint8 c2 = dstHandle[1] * srcHandle[1] >> 8; 93*258b762aSOliver Tappe c2 += dstHandle[1] * ( 9436947c7bSOliver Tappe 255 - ( 9536947c7bSOliver Tappe (255 - dstHandle[1]) 9636947c7bSOliver Tappe * (255 - srcHandle[1]) 9736947c7bSOliver Tappe >> 8 9836947c7bSOliver Tappe ) - c2 9936947c7bSOliver Tappe ) >> 8; 10036947c7bSOliver Tappe c2 = (c2 * dstHandle[3] 10136947c7bSOliver Tappe + srcHandle[1] * (255 - dstHandle[3]) 10236947c7bSOliver Tappe ) >> 8; 10373a2ffbaSStephan Aßmus 10473a2ffbaSStephan Aßmus uint8 c3 = dstHandle[2] * srcHandle[2] >> 8; 105*258b762aSOliver Tappe c3 += dstHandle[2] * ( 10636947c7bSOliver Tappe 255 - ( 10736947c7bSOliver Tappe (255 - dstHandle[2]) 10836947c7bSOliver Tappe * (255 - srcHandle[2]) 10936947c7bSOliver Tappe >> 8 11036947c7bSOliver Tappe ) - c3 11136947c7bSOliver Tappe ) >> 8; 11236947c7bSOliver Tappe c3 = (c3 * dstHandle[3] 11336947c7bSOliver Tappe + srcHandle[2] * (255 - dstHandle[3]) 11436947c7bSOliver Tappe ) >> 8; 11573a2ffbaSStephan Aßmus 11636947c7bSOliver Tappe blend_colors(dstHandle, 11736947c7bSOliver Tappe (srcHandle[3] * alphaOverride) >> 8, c1, c2, c3); 11873a2ffbaSStephan Aßmus } 11973a2ffbaSStephan Aßmus srcHandle += 4; 12073a2ffbaSStephan Aßmus dstHandle += 4; 12173a2ffbaSStephan Aßmus } 12273a2ffbaSStephan Aßmus src += bpr; 12373a2ffbaSStephan Aßmus dst += bpr; 12473a2ffbaSStephan Aßmus } 12573a2ffbaSStephan Aßmus break; 12673a2ffbaSStephan Aßmus 12773a2ffbaSStephan Aßmus case MODE_LIGHTEN: 12873a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 12973a2ffbaSStephan Aßmus uint8* srcHandle = src; 13073a2ffbaSStephan Aßmus uint8* dstHandle = dst; 13173a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 13273a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 13373a2ffbaSStephan Aßmus // compose 13436947c7bSOliver Tappe uint8 c1 13536947c7bSOliver Tappe = (max_c(srcHandle[0], dstHandle[0]) * dstHandle[3] 13673a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255; 13736947c7bSOliver Tappe uint8 c2 13836947c7bSOliver Tappe = (max_c(srcHandle[1], dstHandle[1]) * dstHandle[3] 13973a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255; 14036947c7bSOliver Tappe uint8 c3 14136947c7bSOliver Tappe = (max_c(srcHandle[2], dstHandle[2]) * dstHandle[3] 14273a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255; 14336947c7bSOliver Tappe blend_colors(dstHandle, 14436947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3); 14573a2ffbaSStephan Aßmus } 14673a2ffbaSStephan Aßmus srcHandle += 4; 14773a2ffbaSStephan Aßmus dstHandle += 4; 14873a2ffbaSStephan Aßmus } 14973a2ffbaSStephan Aßmus src += bpr; 15073a2ffbaSStephan Aßmus dst += bpr; 15173a2ffbaSStephan Aßmus } 15273a2ffbaSStephan Aßmus break; 15373a2ffbaSStephan Aßmus 15473a2ffbaSStephan Aßmus case MODE_DARKEN: 15573a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 15673a2ffbaSStephan Aßmus uint8* srcHandle = src; 15773a2ffbaSStephan Aßmus uint8* dstHandle = dst; 15873a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 15973a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 16073a2ffbaSStephan Aßmus // compose 16136947c7bSOliver Tappe uint8 c1 16236947c7bSOliver Tappe = (min_c(srcHandle[0], dstHandle[0]) * dstHandle[3] 16373a2ffbaSStephan Aßmus + srcHandle[0] * (255 - dstHandle[3])) / 255; 16436947c7bSOliver Tappe uint8 c2 16536947c7bSOliver Tappe = (min_c(srcHandle[1], dstHandle[1]) * dstHandle[3] 16673a2ffbaSStephan Aßmus + srcHandle[1] * (255 - dstHandle[3])) / 255; 16736947c7bSOliver Tappe uint8 c3 16836947c7bSOliver Tappe = (min_c(srcHandle[2], dstHandle[2]) * dstHandle[3] 16973a2ffbaSStephan Aßmus + srcHandle[2] * (255 - dstHandle[3])) / 255; 17036947c7bSOliver Tappe blend_colors(dstHandle, 17136947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3); 17273a2ffbaSStephan Aßmus } 17373a2ffbaSStephan Aßmus srcHandle += 4; 17473a2ffbaSStephan Aßmus dstHandle += 4; 17573a2ffbaSStephan Aßmus } 17673a2ffbaSStephan Aßmus src += bpr; 17773a2ffbaSStephan Aßmus dst += bpr; 17873a2ffbaSStephan Aßmus } 17973a2ffbaSStephan Aßmus break; 18073a2ffbaSStephan Aßmus 18173a2ffbaSStephan Aßmus case MODE_REPLACE_RED: 18273a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 18373a2ffbaSStephan Aßmus uint8* srcHandle = src; 18473a2ffbaSStephan Aßmus uint8* dstHandle = dst; 18573a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 18673a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 18773a2ffbaSStephan Aßmus // compose 18873a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 18973a2ffbaSStephan Aßmus dstHandle[2] = (srcHandle[2] * alpha 19073a2ffbaSStephan Aßmus + dstHandle[2] * (65025 - alpha)) / 65025; 19173a2ffbaSStephan Aßmus } 19273a2ffbaSStephan Aßmus srcHandle += 4; 19373a2ffbaSStephan Aßmus dstHandle += 4; 19473a2ffbaSStephan Aßmus } 19573a2ffbaSStephan Aßmus src += bpr; 19673a2ffbaSStephan Aßmus dst += bpr; 19773a2ffbaSStephan Aßmus } 19873a2ffbaSStephan Aßmus break; 19973a2ffbaSStephan Aßmus 20073a2ffbaSStephan Aßmus case MODE_REPLACE_GREEN: 20173a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 20273a2ffbaSStephan Aßmus uint8* srcHandle = src; 20373a2ffbaSStephan Aßmus uint8* dstHandle = dst; 20473a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 20573a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 20673a2ffbaSStephan Aßmus // compose 20773a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 20873a2ffbaSStephan Aßmus dstHandle[1] = (srcHandle[1] * alpha 20973a2ffbaSStephan Aßmus + dstHandle[1] * (65025 - alpha)) / 65025; 21073a2ffbaSStephan Aßmus } 21173a2ffbaSStephan Aßmus srcHandle += 4; 21273a2ffbaSStephan Aßmus dstHandle += 4; 21373a2ffbaSStephan Aßmus } 21473a2ffbaSStephan Aßmus src += bpr; 21573a2ffbaSStephan Aßmus dst += bpr; 21673a2ffbaSStephan Aßmus } 21773a2ffbaSStephan Aßmus break; 21873a2ffbaSStephan Aßmus 21973a2ffbaSStephan Aßmus case MODE_REPLACE_BLUE: 22073a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 22173a2ffbaSStephan Aßmus uint8* srcHandle = src; 22273a2ffbaSStephan Aßmus uint8* dstHandle = dst; 22373a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 22473a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 22573a2ffbaSStephan Aßmus // compose 22673a2ffbaSStephan Aßmus uint32 alpha = srcHandle[3] * alphaOverride; 22773a2ffbaSStephan Aßmus dstHandle[0] = (srcHandle[0] * alpha 22873a2ffbaSStephan Aßmus + dstHandle[0] * (65025 - alpha)) / 65025; 22973a2ffbaSStephan Aßmus } 23073a2ffbaSStephan Aßmus srcHandle += 4; 23173a2ffbaSStephan Aßmus dstHandle += 4; 23273a2ffbaSStephan Aßmus } 23373a2ffbaSStephan Aßmus src += bpr; 23473a2ffbaSStephan Aßmus dst += bpr; 23573a2ffbaSStephan Aßmus } 23673a2ffbaSStephan Aßmus break; 23773a2ffbaSStephan Aßmus 23873a2ffbaSStephan Aßmus case MODE_MULTIPLY_INVERSE_ALPHA: 23973a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 24073a2ffbaSStephan Aßmus uint8* srcHandle = src; 24173a2ffbaSStephan Aßmus uint8* dstHandle = dst; 24273a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 24373a2ffbaSStephan Aßmus // compose 24473a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], 255 - srcHandle[3]); 24536947c7bSOliver Tappe dstHandle[3] = ( 24636947c7bSOliver Tappe dstHandle[3] * (255 - alphaOverride) 24736947c7bSOliver Tappe + temp * alphaOverride 24836947c7bSOliver Tappe ) / 255; 24973a2ffbaSStephan Aßmus srcHandle += 4; 25073a2ffbaSStephan Aßmus dstHandle += 4; 25173a2ffbaSStephan Aßmus } 25273a2ffbaSStephan Aßmus src += bpr; 25373a2ffbaSStephan Aßmus dst += bpr; 25473a2ffbaSStephan Aßmus } 25573a2ffbaSStephan Aßmus break; 25673a2ffbaSStephan Aßmus 25773a2ffbaSStephan Aßmus case MODE_MULTIPLY_ALPHA: 25873a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 25973a2ffbaSStephan Aßmus uint8* srcHandle = src; 26073a2ffbaSStephan Aßmus uint8* dstHandle = dst; 26173a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 26273a2ffbaSStephan Aßmus // compose 26373a2ffbaSStephan Aßmus uint8 temp = min_c(dstHandle[3], srcHandle[3]); 26436947c7bSOliver Tappe dstHandle[3] = ( 26536947c7bSOliver Tappe dstHandle[3] * (255 - alphaOverride) 26636947c7bSOliver Tappe + temp * alphaOverride 26736947c7bSOliver Tappe ) / 255; 26873a2ffbaSStephan Aßmus srcHandle += 4; 26973a2ffbaSStephan Aßmus dstHandle += 4; 27073a2ffbaSStephan Aßmus } 27173a2ffbaSStephan Aßmus src += bpr; 27273a2ffbaSStephan Aßmus dst += bpr; 27373a2ffbaSStephan Aßmus } 27473a2ffbaSStephan Aßmus break; 27573a2ffbaSStephan Aßmus 27673a2ffbaSStephan Aßmus case MODE_LUMINANCE: 27773a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 27873a2ffbaSStephan Aßmus uint8* srcHandle = src; 27973a2ffbaSStephan Aßmus uint8* dstHandle = dst; 28073a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 28173a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 28273a2ffbaSStephan Aßmus // compose 28373a2ffbaSStephan Aßmus uint8 r = dstHandle[2]; 28473a2ffbaSStephan Aßmus uint8 g = dstHandle[1]; 28573a2ffbaSStephan Aßmus uint8 b = dstHandle[0]; 28673a2ffbaSStephan Aßmus uint8 alpha = dstHandle[3]; 28736947c7bSOliver Tappe replace_luminance(r, g, b, srcHandle[2], srcHandle[1], 28836947c7bSOliver Tappe srcHandle[0]); 28936947c7bSOliver Tappe blend_colors(dstHandle, 29036947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, b, g, r); 29173a2ffbaSStephan Aßmus dstHandle[3] = alpha; 29273a2ffbaSStephan Aßmus } 29373a2ffbaSStephan Aßmus srcHandle += 4; 29473a2ffbaSStephan Aßmus dstHandle += 4; 29573a2ffbaSStephan Aßmus } 29673a2ffbaSStephan Aßmus src += bpr; 29773a2ffbaSStephan Aßmus dst += bpr; 29873a2ffbaSStephan Aßmus } 29973a2ffbaSStephan Aßmus break; 30073a2ffbaSStephan Aßmus 30173a2ffbaSStephan Aßmus case MODE_INVERSE_MULTIPLY: 30273a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 30373a2ffbaSStephan Aßmus uint8* srcHandle = src; 30473a2ffbaSStephan Aßmus uint8* dstHandle = dst; 30573a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 30673a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 30773a2ffbaSStephan Aßmus // compose 30836947c7bSOliver Tappe uint8 c1 = 255 - ( 30936947c7bSOliver Tappe (((255 - srcHandle[0]) * (255 - dstHandle[0])) 31036947c7bSOliver Tappe / 255) * dstHandle[3] 31136947c7bSOliver Tappe + (255 - srcHandle[0]) * (255 - dstHandle[3]) 31236947c7bSOliver Tappe ) / 255; 31336947c7bSOliver Tappe uint8 c2 = 255 - ( 31436947c7bSOliver Tappe (((255 - srcHandle[1]) * (255 - dstHandle[1])) 31536947c7bSOliver Tappe / 255) * dstHandle[3] 31636947c7bSOliver Tappe + (255 - srcHandle[1]) * (255 - dstHandle[3]) 31736947c7bSOliver Tappe ) / 255; 31836947c7bSOliver Tappe uint8 c3 = 255 - ( 31936947c7bSOliver Tappe (((255 - srcHandle[2]) * (255 - dstHandle[2])) 32036947c7bSOliver Tappe / 255) * dstHandle[3] 32136947c7bSOliver Tappe + (255 - srcHandle[2]) * (255 - dstHandle[3]) 32236947c7bSOliver Tappe ) / 255; 32336947c7bSOliver Tappe blend_colors(dstHandle, 32436947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3); 32573a2ffbaSStephan Aßmus } 32673a2ffbaSStephan Aßmus srcHandle += 4; 32773a2ffbaSStephan Aßmus dstHandle += 4; 32873a2ffbaSStephan Aßmus } 32973a2ffbaSStephan Aßmus src += bpr; 33073a2ffbaSStephan Aßmus dst += bpr; 33173a2ffbaSStephan Aßmus } 33273a2ffbaSStephan Aßmus break; 33373a2ffbaSStephan Aßmus 33473a2ffbaSStephan Aßmus case MODE_MULTIPLY: 33573a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 33673a2ffbaSStephan Aßmus uint8* srcHandle = src; 33773a2ffbaSStephan Aßmus uint8* dstHandle = dst; 33873a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 33973a2ffbaSStephan Aßmus if (srcHandle[3] > 0) { 34073a2ffbaSStephan Aßmus // compose 34136947c7bSOliver Tappe uint8 c1 = ( 34236947c7bSOliver Tappe ((srcHandle[0] * dstHandle[0]) / 255) 34336947c7bSOliver Tappe * dstHandle[3] 34436947c7bSOliver Tappe + srcHandle[0] * (255 - dstHandle[3]) 34536947c7bSOliver Tappe ) / 255; 34636947c7bSOliver Tappe uint8 c2 = ( 34736947c7bSOliver Tappe ((srcHandle[1] * dstHandle[1]) / 255) 34836947c7bSOliver Tappe * dstHandle[3] 34936947c7bSOliver Tappe + srcHandle[1] * (255 - dstHandle[3]) 35036947c7bSOliver Tappe ) / 255; 35136947c7bSOliver Tappe uint8 c3 = ( 35236947c7bSOliver Tappe ((srcHandle[2] * dstHandle[2]) / 255) 35336947c7bSOliver Tappe * dstHandle[3] 35436947c7bSOliver Tappe + srcHandle[2] * (255 - dstHandle[3]) 35536947c7bSOliver Tappe ) / 255; 35636947c7bSOliver Tappe blend_colors(dstHandle, 35736947c7bSOliver Tappe (srcHandle[3] * alphaOverride) / 255, c1, c2, c3); 35873a2ffbaSStephan Aßmus } 35973a2ffbaSStephan Aßmus srcHandle += 4; 36073a2ffbaSStephan Aßmus dstHandle += 4; 36173a2ffbaSStephan Aßmus } 36273a2ffbaSStephan Aßmus src += bpr; 36373a2ffbaSStephan Aßmus dst += bpr; 36473a2ffbaSStephan Aßmus } 36573a2ffbaSStephan Aßmus break; 36673a2ffbaSStephan Aßmus 36773a2ffbaSStephan Aßmus case MODE_NORMAL: 36873a2ffbaSStephan Aßmus default: 36973a2ffbaSStephan Aßmus if (alphaOverride == 255) { 37073a2ffbaSStephan Aßmus // use an optimized version that composes the bitmaps directly 37173a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 37273a2ffbaSStephan Aßmus uint8* srcHandle = src; 37373a2ffbaSStephan Aßmus uint8* dstHandle = dst; 37473a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 37573a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle); 37673a2ffbaSStephan Aßmus srcHandle += 4; 37773a2ffbaSStephan Aßmus dstHandle += 4; 37873a2ffbaSStephan Aßmus } 37973a2ffbaSStephan Aßmus src += bpr; 38073a2ffbaSStephan Aßmus dst += bpr; 38173a2ffbaSStephan Aßmus } 38273a2ffbaSStephan Aßmus } else { 38373a2ffbaSStephan Aßmus for (; top <= bottom; top++) { 38473a2ffbaSStephan Aßmus uint8* srcHandle = src; 38573a2ffbaSStephan Aßmus uint8* dstHandle = dst; 38673a2ffbaSStephan Aßmus for (int32 x = left; x <= right; x++) { 38773a2ffbaSStephan Aßmus blend_colors(dstHandle, srcHandle, alphaOverride); 38873a2ffbaSStephan Aßmus srcHandle += 4; 38973a2ffbaSStephan Aßmus dstHandle += 4; 39073a2ffbaSStephan Aßmus } 39173a2ffbaSStephan Aßmus src += bpr; 39273a2ffbaSStephan Aßmus dst += bpr; 39373a2ffbaSStephan Aßmus } 39473a2ffbaSStephan Aßmus } 39573a2ffbaSStephan Aßmus break; 39673a2ffbaSStephan Aßmus } 39773a2ffbaSStephan Aßmus 39873a2ffbaSStephan Aßmus return status; 39973a2ffbaSStephan Aßmus } 40073a2ffbaSStephan Aßmus 40136947c7bSOliver Tappe 40273a2ffbaSStephan Aßmus // Unarchive 40373a2ffbaSStephan Aßmus status_t 40473a2ffbaSStephan Aßmus Layer::Unarchive(const BMessage* archive) 40573a2ffbaSStephan Aßmus { 40673a2ffbaSStephan Aßmus if (!archive) 40773a2ffbaSStephan Aßmus return B_BAD_VALUE; 40873a2ffbaSStephan Aßmus 40973a2ffbaSStephan Aßmus // restore attributes 41073a2ffbaSStephan Aßmus float alpha; 41173a2ffbaSStephan Aßmus if (archive->FindFloat("alpha", &alpha) == B_OK) { 41273a2ffbaSStephan Aßmus constrain(alpha, 0.0, 1.0); 41373a2ffbaSStephan Aßmus fAlpha = alpha; 41473a2ffbaSStephan Aßmus } else 41573a2ffbaSStephan Aßmus fAlpha = 1.0; 41673a2ffbaSStephan Aßmus if (archive->FindInt32("mode", (int32*)&fMode) < B_OK) 41773a2ffbaSStephan Aßmus fMode = MODE_NORMAL; 41873a2ffbaSStephan Aßmus if (archive->FindInt32("flags", (int32*)&fFlags) < B_OK) 41973a2ffbaSStephan Aßmus fFlags = 0; 42073a2ffbaSStephan Aßmus 42173a2ffbaSStephan Aßmus // delete current contents 42273a2ffbaSStephan Aßmus delete fBitmap; 42373a2ffbaSStephan Aßmus fBitmap = NULL; 42473a2ffbaSStephan Aßmus 42573a2ffbaSStephan Aßmus status_t status = extract_bitmap(&fBitmap, archive, "current bitmap"); 42673a2ffbaSStephan Aßmus if (status < B_OK) 42773a2ffbaSStephan Aßmus return status; 42873a2ffbaSStephan Aßmus 42973a2ffbaSStephan Aßmus // "bounds" is where the layer actually has content 43073a2ffbaSStephan Aßmus BRect bounds; 43173a2ffbaSStephan Aßmus if (archive->FindRect("bounds", &bounds) == B_OK) 43273a2ffbaSStephan Aßmus fBounds = bounds; 43373a2ffbaSStephan Aßmus else 43473a2ffbaSStephan Aßmus fBounds.Set(0.0, 0.0, -1.0, -1.0); 43573a2ffbaSStephan Aßmus 43673a2ffbaSStephan Aßmus // validate status of fBitmap 43773a2ffbaSStephan Aßmus if (!fBitmap) 43873a2ffbaSStephan Aßmus return B_ERROR; 43973a2ffbaSStephan Aßmus 44073a2ffbaSStephan Aßmus status = fBitmap->InitCheck(); 44173a2ffbaSStephan Aßmus if (status < B_OK) { 44273a2ffbaSStephan Aßmus delete fBitmap; 44373a2ffbaSStephan Aßmus fBitmap = NULL; 44473a2ffbaSStephan Aßmus } 44573a2ffbaSStephan Aßmus 44673a2ffbaSStephan Aßmus return status; 44773a2ffbaSStephan Aßmus } 448