* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifdef ICON_O_MATIC
#include "ReferenceImage.h"
#include <algorithm>
#include <new>
#include <Bitmap.h>
#include <Message.h>
#include "CommonPropertyIDs.h"
#include "Property.h"
#include "PropertyObject.h"
#include "Style.h"
using std::nothrow;
ReferenceImage::ReferenceImage(BBitmap* image)
: Shape(new (nothrow) _ICON_NAMESPACE Style()),
fPath(NULL)
{
if (Style() == NULL)
return;
Style()->ReleaseReference();
SetName("<reference image>");
SetImage(image);
double width = (int) Style()->Bitmap()->Bounds().Width() + 1;
double height = (int) Style()->Bitmap()->Bounds().Height() + 1;
double longerSide = std::max(width, height);
ScaleBy(BPoint(0, 0), 64/longerSide, 64/longerSide);
Transform(&width, &height);
TranslateBy(BPoint((64-width)/2, (64-height)/2));
}
ReferenceImage::ReferenceImage(const ReferenceImage& other)
: Shape(new (nothrow) _ICON_NAMESPACE Style()),
fPath(NULL)
{
if (Style() == NULL)
return;
Style()->ReleaseReference();
BBitmap* bitmap = new (nothrow) BBitmap(other.Style()->Bitmap());
if (bitmap == NULL)
return;
SetName(other.Name());
SetImage(bitmap);
SetTransform(other);
Style()->SetAlpha(other.Style()->Alpha());
}
ReferenceImage::ReferenceImage(BMessage* archive)
: Shape(new (nothrow) _ICON_NAMESPACE Style()),
fPath(NULL)
{
Unarchive(archive);
}
ReferenceImage::~ReferenceImage()
{
}
status_t
ReferenceImage::Unarchive(BMessage* archive)
{
status_t ret = IconObject::Unarchive(archive);
if (ret < B_OK)
return ret;
const double* matrix;
ssize_t dataSize;
ret = archive->FindData("transformation", B_DOUBLE_TYPE,
(const void**) &matrix, &dataSize);
if (ret < B_OK)
return ret;
if (dataSize != Transformable::matrix_size * sizeof(double))
return B_BAD_VALUE;
LoadFrom(matrix);
BBitmap* bitmap = dynamic_cast<BBitmap*>(BBitmap::Instantiate(archive));
if (bitmap == NULL)
return B_ERROR;
SetImage(bitmap);
uint8 alpha;
if(archive->FindUInt8("alpha", &alpha) < B_OK)
alpha = 255;
Style()->SetAlpha(alpha);
return B_OK;
}
status_t
ReferenceImage::Archive(BMessage* into, bool deep) const
{
status_t ret = IconObject::Archive(into, deep);
if (ret < B_OK)
return ret;
int32 size = Transformable::matrix_size;
double matrix[size];
StoreTo(matrix);
ret = into->AddData("transformation", B_DOUBLE_TYPE,
matrix, size * sizeof(double));
if (ret < B_OK)
return ret;
ret = Style()->Bitmap()->Archive(into, deep);
if (ret < B_OK)
return ret;
ret = into->AddUInt8("alpha", Style()->Alpha());
return ret;
}
PropertyObject*
ReferenceImage::MakePropertyObject() const
{
PropertyObject* object = IconObject::MakePropertyObject();
object->AddProperty(new IntProperty(PROPERTY_ALPHA, Style()->Alpha(), 0, 255));
return object;
}
bool
ReferenceImage::SetToPropertyObject(const PropertyObject* object)
{
AutoNotificationSuspender _(this);
IconObject::SetToPropertyObject(object);
Style()->SetAlpha(object->Value(PROPERTY_ALPHA, (int32) Style()->Alpha()));
return HasPendingNotifications();
}
status_t
ReferenceImage::InitCheck() const
{
status_t status = Shape::InitCheck();
if (status != B_OK)
return status;
if (Style() == NULL || Style()->Bitmap() == NULL)
return B_NO_MEMORY;
return B_OK;
}
void
ReferenceImage::SetImage(BBitmap* image)
{
if (fPath != NULL) {
Paths()->MakeEmpty();
delete fPath;
fPath = NULL;
}
if (image != NULL) {
Style()->SetBitmap(image);
fPath = new (nothrow) VectorPath();
if (fPath == NULL)
return;
double width = (int) Style()->Bitmap()->Bounds().Width() + 1;
double height = (int) Style()->Bitmap()->Bounds().Height() + 1;
fPath->AddPoint(BPoint(0, 0));
fPath->AddPoint(BPoint(0, height));
fPath->AddPoint(BPoint(width, height));
fPath->AddPoint(BPoint(width, 0));
fPath->SetClosed(true);
Paths()->AddItem(fPath);
}
}
#endif