1/* 2 * Copyright 2006, 2023, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan A��mus <superstippi@gmx.de> 7 * Zardshard 8 */ 9 10#ifdef ICON_O_MATIC 11#include "ReferenceImage.h" 12 13#include <algorithm> 14#include <new> 15 16#include <Bitmap.h> 17#include <Message.h> 18 19#include "CommonPropertyIDs.h" 20#include "Property.h" 21#include "PropertyObject.h" 22#include "Style.h" 23 24using std::nothrow; 25 26 27ReferenceImage::ReferenceImage(BBitmap* image) 28 : Shape(new (nothrow) _ICON_NAMESPACE Style()), 29 fPath(NULL) 30{ 31 if (Style() == NULL) 32 return; 33 Style()->ReleaseReference(); 34 // The shape constructor acquired a reference 35 36 SetName("<reference image>"); 37 SetImage(image); 38 39 double width = (int) Style()->Bitmap()->Bounds().Width() + 1; 40 double height = (int) Style()->Bitmap()->Bounds().Height() + 1; 41 42 // Scale to fill canvas 43 double longerSide = std::max(width, height); 44 ScaleBy(BPoint(0, 0), 64/longerSide, 64/longerSide); 45 46 // Center 47 Transform(&width, &height); 48 TranslateBy(BPoint((64-width)/2, (64-height)/2)); 49} 50 51 52ReferenceImage::ReferenceImage(const ReferenceImage& other) 53 : Shape(new (nothrow) _ICON_NAMESPACE Style()), 54 fPath(NULL) 55{ 56 if (Style() == NULL) 57 return; 58 Style()->ReleaseReference(); 59 // The shape constructor acquired a reference 60 61 BBitmap* bitmap = new (nothrow) BBitmap(other.Style()->Bitmap()); 62 if (bitmap == NULL) 63 return; 64 65 SetName(other.Name()); 66 SetImage(bitmap); 67 SetTransform(other); 68 Style()->SetAlpha(other.Style()->Alpha()); 69} 70 71 72ReferenceImage::ReferenceImage(BMessage* archive) 73 : Shape(new (nothrow) _ICON_NAMESPACE Style()), 74 fPath(NULL) 75{ 76 Unarchive(archive); 77} 78 79 80ReferenceImage::~ReferenceImage() 81{ 82} 83 84 85// #pragma mark - 86 87 88status_t 89ReferenceImage::Unarchive(BMessage* archive) 90{ 91 // IconObject properties 92 status_t ret = IconObject::Unarchive(archive); 93 if (ret < B_OK) 94 return ret; 95 96 // transformation 97 const double* matrix; 98 ssize_t dataSize; 99 ret = archive->FindData("transformation", B_DOUBLE_TYPE, 100 (const void**) &matrix, &dataSize); 101 if (ret < B_OK) 102 return ret; 103 if (dataSize != Transformable::matrix_size * sizeof(double)) 104 return B_BAD_VALUE; 105 LoadFrom(matrix); 106 107 // image 108 BBitmap* bitmap = dynamic_cast<BBitmap*>(BBitmap::Instantiate(archive)); 109 if (bitmap == NULL) 110 return B_ERROR; 111 SetImage(bitmap); 112 113 // alpha 114 uint8 alpha; 115 if(archive->FindUInt8("alpha", &alpha) < B_OK) 116 alpha = 255; 117 Style()->SetAlpha(alpha); 118 119 return B_OK; 120} 121 122 123status_t 124ReferenceImage::Archive(BMessage* into, bool deep) const 125{ 126 status_t ret = IconObject::Archive(into, deep); 127 if (ret < B_OK) 128 return ret; 129 130 // transformation 131 int32 size = Transformable::matrix_size; 132 double matrix[size]; 133 StoreTo(matrix); 134 ret = into->AddData("transformation", B_DOUBLE_TYPE, 135 matrix, size * sizeof(double)); 136 if (ret < B_OK) 137 return ret; 138 139 // image 140 ret = Style()->Bitmap()->Archive(into, deep); 141 if (ret < B_OK) 142 return ret; 143 144 // alpha 145 ret = into->AddUInt8("alpha", Style()->Alpha()); 146 147 return ret; 148} 149 150 151PropertyObject* 152ReferenceImage::MakePropertyObject() const 153{ 154 PropertyObject* object = IconObject::MakePropertyObject(); 155 156 object->AddProperty(new IntProperty(PROPERTY_ALPHA, Style()->Alpha(), 0, 255)); 157 158 return object; 159} 160 161 162bool 163ReferenceImage::SetToPropertyObject(const PropertyObject* object) 164{ 165 AutoNotificationSuspender _(this); 166 IconObject::SetToPropertyObject(object); 167 168 Style()->SetAlpha(object->Value(PROPERTY_ALPHA, (int32) Style()->Alpha())); 169 170 return HasPendingNotifications(); 171} 172 173 174// #pragma mark - 175 176 177status_t 178ReferenceImage::InitCheck() const 179{ 180 status_t status = Shape::InitCheck(); 181 if (status != B_OK) 182 return status; 183 184 if (Style() == NULL || Style()->Bitmap() == NULL) 185 return B_NO_MEMORY; 186 187 return B_OK; 188} 189 190 191// #pragma mark - 192 193 194void 195ReferenceImage::SetImage(BBitmap* image) 196{ 197 if (fPath != NULL) { 198 Paths()->MakeEmpty(); 199 delete fPath; 200 fPath = NULL; 201 } 202 203 if (image != NULL) { 204 // Update style 205 Style()->SetBitmap(image); 206 207 // Update shape 208 fPath = new (nothrow) VectorPath(); 209 if (fPath == NULL) 210 return; 211 212 double width = (int) Style()->Bitmap()->Bounds().Width() + 1; 213 double height = (int) Style()->Bitmap()->Bounds().Height() + 1; 214 fPath->AddPoint(BPoint(0, 0)); 215 fPath->AddPoint(BPoint(0, height)); 216 fPath->AddPoint(BPoint(width, height)); 217 fPath->AddPoint(BPoint(width, 0)); 218 fPath->SetClosed(true); 219 Paths()->AddItem(fPath); 220 } 221} 222 223#endif // ICON_O_MATIC 224 225