Icon-O-Matic: Add reference images

Fixes #2748

Also fixes a comment misstating a function's name and code style.

Change-Id: I609a1f1e100ded647818e70b428cedc48cf29036
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6604
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Zardshard
2023-06-18 11:25:54 +00:00
committed by Adrien Destugues
parent b799d160f2
commit 098eaec630
50 changed files with 1466 additions and 534 deletions
+1 -1
View File
@@ -435,7 +435,7 @@ void
CanvasView::_DrawInto(BView* view, BRect updateRect)
{
if (fDirtyIconArea.IsValid()) {
fRenderer->Render(fDirtyIconArea);
fRenderer->Render(fDirtyIconArea, true);
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
}
+18 -3
View File
@@ -1,6 +1,10 @@
/*
* Copyright 2006, 2011, Stephan Aßmus <[email protected]>.
* Copyright 2023 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/
@@ -26,6 +30,7 @@
#include "Defines.h"
#include "MainWindow.h"
#include "SavePanel.h"
#include "ShapeListView.h"
#undef B_TRANSLATION_CONTEXT
@@ -123,6 +128,9 @@ IconEditorApp::MessageReceived(BMessage* message)
MainWindow* window;
if (message->FindPointer("window", (void**)&window) == B_OK)
openMessage.AddPointer("window", window);
bool referenceImage;
if (message->FindBool("reference image", &referenceImage) == B_OK)
openMessage.AddBool("reference image", referenceImage);
fOpenPanel->SetMessage(&openMessage);
fOpenPanel->Show();
break;
@@ -216,6 +224,9 @@ IconEditorApp::RefsReceived(BMessage* message)
bool append;
if (message->FindBool("append", &append) != B_OK)
append = false;
bool referenceImage;
if (message->FindBool("reference image", &referenceImage) != B_OK)
referenceImage = false;
MainWindow* window;
if (message->FindPointer("window", (void**)&window) != B_OK)
window = NULL;
@@ -223,11 +234,15 @@ IconEditorApp::RefsReceived(BMessage* message)
if (append && window == NULL)
return;
entry_ref ref;
if (append) {
if (append || referenceImage) {
if (!window->Lock())
return;
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++)
window->Open(ref, true);
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
if (append)
window->Open(ref, true);
if (referenceImage)
window->AddReferenceImage(ref);
}
window->Unlock();
} else {
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
+2
View File
@@ -82,6 +82,8 @@ Application Icon-O-Matic :
# icon/shape
PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp
ShapeContainer.cpp
VectorPath.cpp
+65 -10
View File
@@ -1,6 +1,10 @@
/*
* Copyright 2006-2011, Stephan Aßmus <[email protected]>.
* Copyright 2023, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/
#include "MainWindow.h"
@@ -9,6 +13,7 @@
#include <stdio.h>
#include <Alert.h>
#include <Bitmap.h>
#include <Catalog.h>
#include <Clipboard.h>
#include <GridLayout.h>
@@ -25,8 +30,10 @@
#include <MenuField.h>
#include <MenuItem.h>
#include <Message.h>
#include <MimeType.h>
#include <Screen.h>
#include <ScrollView.h>
#include <TranslationUtils.h>
#include "support_ui.h"
@@ -73,6 +80,8 @@
#include "Icon.h"
#include "MultipleManipulatorState.h"
#include "PathManipulator.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h"
#include "ShapeContainer.h"
#include "ShapeListView.h"
@@ -207,6 +216,24 @@ MainWindow::MessageReceived(BMessage* message)
case B_REFS_RECEIVED:
case B_SIMPLE_DATA:
{
entry_ref ref;
if (message->FindRef("refs", &ref) != B_OK)
break;
// Check if this is best represented by a ReferenceImage
BMimeType type;
if (BMimeType::GuessMimeType(&ref, &type) == B_OK) {
BMimeType superType;
if (type.GetSupertype(&superType) == B_OK
&& superType == BMimeType("image")
&& !(type == BMimeType("image/svg+xml"))
&& !(type == BMimeType("image/x-hvif"))) {
AddReferenceImage(ref);
break;
}
}
// If our icon is empty, open the file in this window,
// otherwise forward to the application which will open
// it in another window, unless we append.
@@ -214,9 +241,7 @@ MainWindow::MessageReceived(BMessage* message)
if (fDocument->Icon()->Styles()->CountStyles() == 0
&& fDocument->Icon()->Paths()->CountPaths() == 0
&& fDocument->Icon()->Shapes()->CountShapes() == 0) {
entry_ref ref;
if (message->FindRef("refs", &ref) == B_OK)
Open(ref);
Open(ref);
break;
}
if (modifiers() & B_SHIFT_KEY) {
@@ -226,6 +251,7 @@ MainWindow::MessageReceived(BMessage* message)
}
be_app->PostMessage(message);
break;
}
case B_PASTE:
case B_MIME_DATA:
@@ -272,15 +298,23 @@ MainWindow::MessageReceived(BMessage* message)
}
case MSG_OPEN:
{
// If our icon is empty, we want the icon to open in this
// window.
if (fDocument->Icon()->Styles()->CountStyles() == 0
bool emptyDocument = fDocument->Icon()->Styles()->CountStyles() == 0
&& fDocument->Icon()->Paths()->CountPaths() == 0
&& fDocument->Icon()->Shapes()->CountShapes() == 0) {
&& fDocument->Icon()->Shapes()->CountShapes() == 0;
bool openingReferenceImage;
if (message->FindBool("reference image", &openingReferenceImage) != B_OK)
openingReferenceImage = false;
if (emptyDocument || openingReferenceImage)
message->AddPointer("window", this);
}
be_app->PostMessage(message);
break;
}
case MSG_SAVE:
case MSG_EXPORT:
@@ -414,11 +448,9 @@ MainWindow::MessageReceived(BMessage* message)
style = fDocument->Icon()->Styles()->StyleAt(0);
}
Shape* shape = new (nothrow) Shape(style);
Shape* shapes[1];
shapes[0] = shape;
PathSourceShape* shape = new (nothrow) PathSourceShape(style);
AddShapesCommand* shapeCommand = new (nothrow) AddShapesCommand(
fDocument->Icon()->Shapes(), shapes, 1,
fDocument->Icon()->Shapes(), (Shape**) &shape, 1,
fDocument->Icon()->Shapes()->CountShapes(),
fDocument->Selection());
@@ -824,6 +856,29 @@ MainWindow::Open(const BMessenger& externalObserver, const uint8* data,
}
void
MainWindow::AddReferenceImage(const entry_ref& ref)
{
BBitmap* image = BTranslationUtils::GetBitmap(&ref);
if (image == NULL)
return;
Shape* shape = new (nothrow) ReferenceImage(image);
if (shape == NULL)
return;
AddShapesCommand* shapeCommand = new (nothrow) AddShapesCommand(
fDocument->Icon()->Shapes(), &shape, 1,
fDocument->Icon()->Shapes()->CountShapes(),
fDocument->Selection());
if (shapeCommand == NULL) {
delete shape;
return;
}
fDocument->CommandStack()->Perform(shapeCommand);
}
void
MainWindow::SetIcon(Icon* icon)
{
+5
View File
@@ -1,6 +1,10 @@
/*
* Copyright 2006-2010, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2023, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
@@ -73,6 +77,7 @@ public:
bool append = false);
void Open(const BMessenger& externalObserver,
const uint8* data, size_t size);
void AddReferenceImage(const entry_ref& ref);
void StoreSettings(BMessage* archive);
void RestoreSettings(const BMessage* archive);
@@ -63,7 +63,7 @@ IconObject::SelectedChanged()
// Unarchive
status_t
IconObject::Unarchive(const BMessage* archive)
IconObject::Unarchive(BMessage* archive)
{
if (!archive)
return B_BAD_VALUE;
+1 -1
View File
@@ -31,7 +31,7 @@ class IconObject : public Observable,
virtual void SelectedChanged();
// IconObject
virtual status_t Unarchive(const BMessage* archive);
virtual status_t Unarchive(BMessage* archive);
virtual status_t Archive(BMessage* into,
bool deep = true) const;
@@ -30,6 +30,9 @@ name_for_id(int32 id)
name = B_TRANSLATE("Name");
break;
case PROPERTY_ALPHA:
name = B_TRANSLATE("Alpha");
break;
case PROPERTY_OPACITY:
name = B_TRANSLATE("Opacity");
break;
@@ -14,7 +14,8 @@
enum {
PROPERTY_NAME = 'name',
PROPERTY_OPACITY = 'alpa',
PROPERTY_ALPHA = 'alpa',
PROPERTY_OPACITY = 'opac',
PROPERTY_COLOR = 'colr',
PROPERTY_WIDTH = 'wdth',
+1 -1
View File
@@ -57,7 +57,7 @@ void
IconView::Draw(BRect updateRect)
{
if (fDirtyIconArea.IsValid()) {
fRenderer->Render(fDirtyIconArea);
fRenderer->Render(fDirtyIconArea, false);
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
}
+6 -5
View File
@@ -26,6 +26,7 @@
#include "CommandStack.h"
#include "MovePathsCommand.h"
#include "Observer.h"
#include "PathSourceShape.h"
#include "RemovePathsCommand.h"
#include "ReversePathCommand.h"
#include "RotatePathIndicesCommand.h"
@@ -242,7 +243,7 @@ public:
// ShapePathListener
void SetShape(Shape* shape)
void SetShape(PathSourceShape* shape)
{
if (fShape == shape)
return;
@@ -263,8 +264,8 @@ public:
}
private:
PathListView* fListView;
Shape* fShape;
PathListView* fListView;
PathSourceShape* fShape;
};
@@ -868,8 +869,8 @@ PathListView::SetCurrentShape(Shape* shape)
if (fCurrentShape == shape)
return;
fCurrentShape = shape;
fShapePathListener->SetShape(shape);
fCurrentShape = dynamic_cast<PathSourceShape*>(shape);
fShapePathListener->SetShape(fCurrentShape);
_UpdateMarks();
}
+3 -2
View File
@@ -18,6 +18,7 @@ class BMenuItem;
_BEGIN_ICON_NAMESPACE
class VectorPath;
class PathSourceShape;
class Shape;
class ShapeContainer;
_END_ICON_NAMESPACE
@@ -74,7 +75,7 @@ class PathListView : public SimpleListView,
void SetMenu(BMenu* menu);
void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const
PathSourceShape* CurrentShape() const
{ return fCurrentShape; }
private:
@@ -106,7 +107,7 @@ class PathListView : public SimpleListView,
ShapeContainer* fShapeContainer;
CommandStack* fCommandStack;
Shape* fCurrentShape;
PathSourceShape* fCurrentShape;
// those path items will be marked that
// are referenced by this shape
+172 -90
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
* Copyright 2006-2012, 2023, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "ShapeListView.h"
@@ -27,9 +28,12 @@
#include "CommandStack.h"
#include "CompoundCommand.h"
#include "FreezeTransformationCommand.h"
#include "MainWindow.h"
#include "MoveShapesCommand.h"
#include "Observer.h"
#include "ReferenceImage.h"
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "RemoveShapesCommand.h"
#include "ResetTransformationCommand.h"
#include "Selection.h"
@@ -214,8 +218,19 @@ ShapeListView::MessageReceived(BMessage* message)
if (count < 0)
break;
BList pathSourceShapes;
for (int i = 0; i < count; i++) {
Shape* shape = (Shape*) shapes.ItemAtFast(i);
if (dynamic_cast<PathSourceShape*>(shape) != NULL)
pathSourceShapes.AddItem(shape);
}
count = pathSourceShapes.CountItems();
FreezeTransformationCommand* command
= new FreezeTransformationCommand((Shape**)shapes.Items(),
= new FreezeTransformationCommand(
(PathSourceShape**)pathSourceShapes.Items(),
count);
fCommandStack->Perform(command);
@@ -239,27 +254,51 @@ ShapeListView::MakeDragMessage(BMessage* message) const
ShapeListItem* item = dynamic_cast<ShapeListItem*>(
ItemAt(CurrentSelection(i)));
if (item != NULL && item->shape != NULL) {
message->AddPointer("shape", (void*)item->shape);
// Add archives of everything this Shape uses
BMessage archive;
BMessage styleArchive;
item->shape->Style()->Archive(&styleArchive, true);
archive.AddMessage("style", &styleArchive);
PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(item->shape);
if (pathSourceShape != NULL) {
message->AddInt32("type", PathSourceShape::archive_code);
PathContainer* paths = item->shape->Paths();
for (int32 j = 0; j < paths->CountPaths(); j++) {
BMessage pathArchive;
paths->PathAt(j)->Archive(&pathArchive, true);
archive.AddMessage("path", &pathArchive);
PathSourceShape* shape = pathSourceShape;
message->AddPointer("shape", (void*)shape);
// Add archives of everything this Shape uses
BMessage archive;
BMessage styleArchive;
shape->Style()->Archive(&styleArchive, true);
archive.AddMessage("style", &styleArchive);
PathContainer* paths = shape->Paths();
for (int32 j = 0; j < paths->CountPaths(); j++) {
BMessage pathArchive;
paths->PathAt(j)->Archive(&pathArchive, true);
archive.AddMessage("path", &pathArchive);
}
BMessage shapeArchive;
shape->Archive(&shapeArchive, true);
archive.AddMessage("shape", &shapeArchive);
message->AddMessage("shape archive", &archive);
continue;
}
BMessage shapeArchive;
item->shape->Archive(&shapeArchive, true);
archive.AddMessage("shape", &shapeArchive);
ReferenceImage* referenceImage = dynamic_cast<ReferenceImage*>(item->shape);
if (referenceImage != NULL) {
message->AddInt32("type", ReferenceImage::archive_code);
message->AddMessage("shape archive", &archive);
message->AddPointer("shape", (void*)referenceImage);
// Add archives of everything this Shape uses
BMessage archive;
BMessage shapeArchive;
referenceImage->Archive(&shapeArchive, true);
archive.AddMessage("shape", &shapeArchive);
message->AddMessage("shape archive", &archive);
continue;
}
} else
break;
}
@@ -300,87 +339,108 @@ ShapeListView::HandleDropMessage(const BMessage* message, int32 dropIndex)
BList paths;
BList shapes;
while (true) {
BMessage archive;
if (message->FindMessage("shape archive", index, &archive) != B_OK)
int32 type;
if (message->FindInt32("type", index, &type) != B_OK)
break;
// Extract the shape archive
BMessage shapeArchive;
if (archive.FindMessage("shape", &shapeArchive) != B_OK)
break;
// Extract the style
BMessage styleArchive;
if (archive.FindMessage("style", &styleArchive) != B_OK)
break;
Style* style = new Style(&styleArchive);
if (style == NULL)
break;
Style* styleToAssign = style;
// Try to find an existing style that is the same as the extracted
// style and use that one instead.
for (int32 i = 0; i < fStyleContainer->CountStyles(); i++) {
Style* other = fStyleContainer->StyleAtFast(i);
if (*other == *style) {
styleToAssign = other;
delete style;
style = NULL;
if (type == PathSourceShape::archive_code) {
BMessage archive;
if (message->FindMessage("shape archive", index, &archive) != B_OK)
break;
}
}
if (style != NULL && !styles.AddItem(style)) {
delete style;
break;
}
// Create the shape using the given style
Shape* shape = new(std::nothrow) Shape(styleToAssign);
if (shape == NULL)
break;
// Extract the shape archive
BMessage shapeArchive;
if (archive.FindMessage("shape", &shapeArchive) != B_OK)
break;
if (shape->Unarchive(&shapeArchive) != B_OK
|| !shapes.AddItem(shape)) {
delete shape;
if (style != NULL) {
styles.RemoveItem(style);
delete style;
}
break;
}
// Extract the paths
int pathIndex = 0;
while (true) {
BMessage pathArchive;
if (archive.FindMessage("path", pathIndex, &pathArchive) != B_OK)
// Extract the style
BMessage styleArchive;
if (archive.FindMessage("style", &styleArchive) != B_OK)
break;
VectorPath* path = new(nothrow) VectorPath(&pathArchive);
if (path == NULL)
Style* style = new Style(&styleArchive);
if (style == NULL)
break;
VectorPath* pathToInclude = path;
for (int32 i = 0; i < fPathContainer->CountPaths(); i++) {
VectorPath* other = fPathContainer->PathAtFast(i);
if (*other == *path) {
pathToInclude = other;
delete path;
path = NULL;
Style* styleToAssign = style;
// Try to find an existing style that is the same as the extracted
// style and use that one instead.
for (int32 i = 0; i < fStyleContainer->CountStyles(); i++) {
Style* other = fStyleContainer->StyleAtFast(i);
if (*other == *style) {
styleToAssign = other;
delete style;
style = NULL;
break;
}
}
if (path != NULL && !paths.AddItem(path)) {
delete path;
if (style != NULL && !styles.AddItem(style)) {
delete style;
break;
}
shape->Paths()->AddPath(pathToInclude);
pathIndex++;
// Create the shape using the given style
PathSourceShape* shape = new(std::nothrow) PathSourceShape(styleToAssign);
if (shape == NULL)
break;
if (shape->Unarchive(&shapeArchive) != B_OK
|| !shapes.AddItem(shape)) {
delete shape;
if (style != NULL) {
styles.RemoveItem(style);
delete style;
}
break;
}
// Extract the paths
int pathIndex = 0;
while (true) {
BMessage pathArchive;
if (archive.FindMessage("path", pathIndex, &pathArchive) != B_OK)
break;
VectorPath* path = new(nothrow) VectorPath(&pathArchive);
if (path == NULL)
break;
VectorPath* pathToInclude = path;
for (int32 i = 0; i < fPathContainer->CountPaths(); i++) {
VectorPath* other = fPathContainer->PathAtFast(i);
if (*other == *path) {
pathToInclude = other;
delete path;
path = NULL;
break;
}
}
if (path != NULL && !paths.AddItem(path)) {
delete path;
break;
}
shape->Paths()->AddPath(pathToInclude);
pathIndex++;
}
} else if (type == ReferenceImage::archive_code) {
BMessage archive;
if (message->FindMessage("shape archive", index, &archive) != B_OK)
break;
BMessage shapeArchive;
if (archive.FindMessage("shape", &shapeArchive) != B_OK)
break;
ReferenceImage* shape = new (std::nothrow) ReferenceImage(&shapeArchive);
if (shape == NULL)
break;
if (shapes.AddItem(shape) != B_OK)
break;
}
index++;
@@ -462,7 +522,7 @@ ShapeListView::CopyItems(BList& items, int32 toIndex)
for (int32 i = 0; i < count; i++) {
ShapeListItem* item
= dynamic_cast<ShapeListItem*>((BListItem*)items.ItemAtFast(i));
shapes[i] = item ? new(nothrow) Shape(*item->shape) : NULL;
shapes[i] = item ? item->shape->Clone() : NULL;
}
AddShapesCommand* command = new(nothrow) AddShapesCommand(fShapeContainer,
@@ -612,6 +672,10 @@ ShapeListView::SetMenu(BMenu* menu)
fAddWidthPathAndStyleMI = new BMenuItem(
B_TRANSLATE("Add with path & style"), message);
message = new BMessage(MSG_OPEN);
message->AddBool("reference image", true);
fAddReferenceImageMI = new BMenuItem(B_TRANSLATE("Add reference image"), message);
fDuplicateMI = new BMenuItem(B_TRANSLATE("Duplicate"),
new BMessage(MSG_DUPLICATE));
fResetTransformationMI = new BMenuItem(B_TRANSLATE("Reset transformation"),
@@ -630,10 +694,13 @@ ShapeListView::SetMenu(BMenu* menu)
fMenu->AddSeparatorItem();
fMenu->AddItem(fAddReferenceImageMI);
fMenu->AddSeparatorItem();
fMenu->AddItem(fDuplicateMI);
fMenu->AddItem(fResetTransformationMI);
fMenu->AddItem(fFreezeTransformationMI);
fMenu->AddSeparatorItem();
fMenu->AddItem(fRemoveMI);
@@ -753,6 +820,21 @@ ShapeListView::_UpdateMenu()
fResetTransformationMI->SetEnabled(gotSelection);
fFreezeTransformationMI->SetEnabled(gotSelection);
fRemoveMI->SetEnabled(gotSelection);
if (gotSelection) {
bool hasPathSourceShape = false;
int32 count = CountSelectedItems();
for (int32 i = 0; i < count; i++) {
ShapeListItem* item
= dynamic_cast<ShapeListItem*>(ItemAt(CurrentSelection(i)));
bool isPathSourceShape
= item ? dynamic_cast<PathSourceShape*>(item->shape) != NULL : false;
hasPathSourceShape |= isPathSourceShape;
}
fFreezeTransformationMI->SetEnabled(hasPathSourceShape);
}
}
+4 -1
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006-2007, Haiku.
* Copyright 2006-2007, 2023, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifndef SHAPE_LIST_VIEW_H
#define SHAPE_LIST_VIEW_H
@@ -30,6 +31,7 @@ _USING_ICON_NAMESPACE
enum {
MSG_ADD_SHAPE = 'adsh',
MSG_ADD_REFERENCE_IMAGE = 'aimg',
};
class ShapeListView : public SimpleListView,
@@ -95,6 +97,7 @@ class ShapeListView : public SimpleListView,
BMenuItem* fAddWidthPathMI;
BMenuItem* fAddWidthStyleMI;
BMenuItem* fAddWidthPathAndStyleMI;
BMenuItem* fAddReferenceImageMI;
BMenuItem* fDuplicateMI;
BMenuItem* fResetTransformationMI;
BMenuItem* fFreezeTransformationMI;
+10 -7
View File
@@ -25,6 +25,7 @@
#include "CommandStack.h"
#include "GradientTransformable.h"
#include "MoveStylesCommand.h"
#include "PathSourceShape.h"
#include "RemoveStylesCommand.h"
#include "Style.h"
#include "Observer.h"
@@ -236,7 +237,7 @@ public:
}
// ShapeStyleListener
void SetShape(Shape* shape)
void SetShape(PathSourceShape* shape)
{
if (fShape == shape)
return;
@@ -250,14 +251,14 @@ public:
fShape->AddListener(this);
}
Shape* CurrentShape() const
PathSourceShape* CurrentShape() const
{
return fShape;
}
private:
StyleListView* fListView;
Shape* fShape;
StyleListView* fListView;
PathSourceShape* fShape;
};
@@ -769,11 +770,13 @@ StyleListView::SetCurrentColor(CurrentColor* color)
void
StyleListView::SetCurrentShape(Shape* shape)
{
if (fCurrentShape == shape)
PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(shape);
if (fCurrentShape == pathSourceShape)
return;
fCurrentShape = shape;
fShapeListener->SetShape(shape);
fCurrentShape = pathSourceShape;
fShapeListener->SetShape(pathSourceShape);
_UpdateMarks();
}
+3 -2
View File
@@ -19,6 +19,7 @@ class ShapeStyleListener;
class StyleListItem;
_BEGIN_ICON_NAMESPACE
class PathSourceShape;
class Shape;
class ShapeContainer;
class ShapeListener;
@@ -72,7 +73,7 @@ public:
void SetCurrentColor(CurrentColor* color);
void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const
PathSourceShape* CurrentShape() const
{ return fCurrentShape; }
private:
@@ -93,7 +94,7 @@ private:
CommandStack* fCommandStack;
CurrentColor* fCurrentColor;
Shape* fCurrentShape;
PathSourceShape* fCurrentShape;
// the style item will be marked that
// is referenced by this shape
@@ -24,6 +24,7 @@
#include "AddTransformersCommand.h"
#include "CommandStack.h"
#include "MoveTransformersCommand.h"
#include "ReferenceImage.h"
#include "RemoveTransformersCommand.h"
#include "Transformer.h"
#include "TransformerFactory.h"
@@ -386,20 +387,31 @@ TransformerListView::SetMenu(BMenu* menu)
return;
BMenu* addMenu = new BMenu(B_TRANSLATE("Add"));
int32 cookie = 0;
uint32 type;
BString name;
while (TransformerFactory::NextType(&cookie, &type, &name)) {
// TODO: Disable the "Transformation" and "Perspective" transformers
// since they are not very useful or even implemented at all.
if (name == B_TRANSLATE("Transformation")
|| name == B_TRANSLATE("Perspective"))
continue;
// End of TODO.
BMessage* message = new BMessage(MSG_ADD_TRANSFORMER);
message->AddInt32("type", type);
addMenu->AddItem(new BMenuItem(name.String(), message));
}
// Keep translated strings that were brought in from another file
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Transformation"
BMessage* message = new BMessage(MSG_ADD_TRANSFORMER);
message->AddInt32("type", CONTOUR_TRANSFORMER);
fContourMI = new BMenuItem(B_TRANSLATE("Contour"), message);
message = new BMessage(MSG_ADD_TRANSFORMER);
message->AddInt32("type", STROKE_TRANSFORMER);
fStrokeMI = new BMenuItem(B_TRANSLATE("Stroke"), message);
// message = new BMessage(MSG_ADD_TRANSFORMER);
// message->AddInt32("type", PERSPECTIVE_TRANSFORMER);
// fPerspectiveMI = new BMenuItem(B_TRANSLATE("Perspective"), message);
// message = new BMessage(MSG_ADD_TRANSFORMER);
// message->AddInt32("type", AFFINE_TRANSFORMER);
// fTransformationMI = new BMenuItem(B_TRANSLATE("Transformation"), message);
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-TransformersList"
addMenu->AddItem(fContourMI);
addMenu->AddItem(fStrokeMI);
addMenu->SetTargetForItems(this);
fMenu->AddItem(addMenu);
@@ -480,4 +492,8 @@ void
TransformerListView::_UpdateMenu()
{
fMenu->SetEnabled(fShape != NULL);
bool isReferenceImage = dynamic_cast<ReferenceImage*>(fShape) != NULL;
fContourMI->SetEnabled(!isReferenceImage);
fStrokeMI->SetEnabled(!isReferenceImage);
}
@@ -14,6 +14,7 @@
class BMenu;
class BMenuItem;
class CommandStack;
class TransformerItem;
class Selection;
@@ -79,6 +80,8 @@ class TransformerListView : public SimpleListView,
CommandStack* fCommandStack;
BMenu* fMenu;
BMenuItem* fContourMI;
BMenuItem* fStrokeMI;
};
#endif // TRANSFORMER_LIST_VIEW_H
@@ -15,6 +15,8 @@
#include "Icon.h"
#include "IconRenderer.h"
#include "ReferenceImage.h"
// constructor
BitmapExporter::BitmapExporter(uint32 size)
@@ -53,7 +55,7 @@ BitmapExporter::Export(const Icon* icon, BPositionIO* stream)
IconRenderer renderer(&bitmap);
renderer.SetIcon(icon);
renderer.SetScale(fSize / 64.0);
renderer.Render();
renderer.Render(false);
// renderer.Demultiply(&bitmap);
// save bitmap to translator
@@ -1,9 +1,10 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "FlatIconExporter.h"
@@ -24,7 +25,9 @@
#include "LittleEndianBuffer.h"
#include "PathCommandQueue.h"
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "PerspectiveTransformer.h"
#include "ReferenceImage.h"
#include "Shape.h"
#include "StrokeTransformer.h"
#include "Style.h"
@@ -477,7 +480,7 @@ _WriteTransformer(LittleEndianBuffer& buffer, Transformer* t)
// _WritePathSourceShape
static bool
_WritePathSourceShape(LittleEndianBuffer& buffer, Shape* shape,
_WritePathSourceShape(LittleEndianBuffer& buffer, PathSourceShape* shape,
StyleContainer* styles, PathContainer* paths)
{
// find out which style this shape uses
@@ -575,16 +578,31 @@ FlatIconExporter::_WriteShapes(LittleEndianBuffer& buffer,
PathContainer* paths,
ShapeContainer* shapes)
{
if (shapes->CountShapes() > 255)
return B_RESULT_NOT_REPRESENTABLE;
uint8 shapeCount = min_c(255, shapes->CountShapes());
if (!buffer.Write(shapeCount))
return B_NO_MEMORY;
uint32 shapeCount = shapes->CountShapes();
// Count the number of exportable shapes
uint32 pathShapeCount = 0;
for (uint32 i = 0; i < shapeCount; i++) {
Shape* shape = shapes->ShapeAtFast(i);
if (!_WritePathSourceShape(buffer, shape, styles, paths))
return B_ERROR;
if (dynamic_cast<PathSourceShape*>(shape) != NULL)
pathShapeCount++;
}
// Write number of exportable shapes
if (pathShapeCount > 255)
return B_RESULT_NOT_REPRESENTABLE;
if (!buffer.Write((uint8) pathShapeCount))
return B_NO_MEMORY;
// Export each shape
for (uint32 i = 0; i < shapeCount; i++) {
Shape* shape = shapes->ShapeAtFast(i);
PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(shape);
if (pathSourceShape != NULL) {
if (!_WritePathSourceShape(buffer, pathSourceShape, styles, paths))
return B_ERROR;
}
}
return B_OK;
@@ -1,9 +1,10 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "MessageExporter.h"
@@ -16,6 +17,8 @@
#include "Defines.h"
#include "Icon.h"
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h"
#include "Style.h"
#include "StyleContainer.h"
@@ -150,26 +153,40 @@ MessageExporter::_Export(const Shape* shape,
const StyleContainer* globalStyles,
BMessage* into) const
{
// NOTE: when the same path is used in two different
// documents, and these are to be merged, each path
// having a "globally unique" id would make it possible
// to reference the same path across documents...
// For now, we simply use the index of the path in the
// globalPaths container.
status_t ret = B_OK;
// index of used style
Style* style = shape->Style();
status_t ret = into->AddInt32("style ref", globalStyles->IndexOf(style));
const PathSourceShape* pathSourceShape = dynamic_cast<const PathSourceShape*>(shape);
if (pathSourceShape != NULL) {
ret = into->AddInt32("type", PathSourceShape::archive_code);
// indices of used paths
if (ret == B_OK) {
int32 count = shape->Paths()->CountPaths();
for (int32 i = 0; i < count; i++) {
VectorPath* path = shape->Paths()->PathAtFast(i);
ret = into->AddInt32("path ref", globalPaths->IndexOf(path));
if (ret < B_OK)
break;
// NOTE: when the same path is used in two different
// documents, and these are to be merged, each path
// having a "globally unique" id would make it possible
// to reference the same path across documents...
// For now, we simply use the index of the path in the
// globalPaths container.
// index of used style
if (ret == B_OK) {
Style* style = pathSourceShape->Style();
ret = into->AddInt32("style ref", globalStyles->IndexOf(style));
}
// indices of used paths
if (ret == B_OK) {
int32 count = pathSourceShape->Paths()->CountPaths();
for (int32 i = 0; i < count; i++) {
VectorPath* path = pathSourceShape->Paths()->PathAtFast(i);
ret = into->AddInt32("path ref", globalPaths->IndexOf(path));
if (ret < B_OK)
break;
}
}
}
const ReferenceImage* referenceImage = dynamic_cast<const ReferenceImage*>(shape);
if (referenceImage != NULL) {
ret = into->AddInt32("type", ReferenceImage::archive_code);
}
// Shape properties
@@ -29,7 +29,7 @@
#include "Defines.h"
#include "Icon.h"
#include "PathContainer.h"
#include "Shape.h"
#include "PathSourceShape.h"
#include "Style.h"
#include "StyleContainer.h"
#include "VectorPath.h"
@@ -45,7 +45,7 @@ using std::nothrow;
class ShapeIterator : public BShapeIterator {
public:
ShapeIterator(Icon *icon, Shape *to, BPoint offset, const char *name);
ShapeIterator(Icon *icon, PathSourceShape *to, BPoint offset, const char *name);
~ShapeIterator() {};
virtual status_t IterateMoveTo(BPoint *point);
@@ -58,7 +58,7 @@ class ShapeIterator : public BShapeIterator {
void NextPath();
Icon *fIcon;
Shape *fShape;
PathSourceShape *fShape;
VectorPath *fPath;
BPoint fOffset;
const char *fName;
@@ -66,7 +66,7 @@ class ShapeIterator : public BShapeIterator {
bool fHasLastPoint;
};
ShapeIterator::ShapeIterator(Icon *icon, Shape *to, BPoint offset,
ShapeIterator::ShapeIterator(Icon *icon, PathSourceShape *to, BPoint offset,
const char *name)
{
CALLED();
@@ -328,7 +328,7 @@ StyledTextImporter::_Import(Icon* icon, const char *text, text_run_array *runs)
if (glyph.Bounds().IsValid()) {
//offset.x += glyph.Bounds().Width();
offset.x += charWidth;
Shape* shape = new (nothrow) Shape(NULL);
PathSourceShape* shape = new (nothrow) PathSourceShape(NULL);
if (shape == NULL)
return B_NO_MEMORY;
shape->SetName(glyphName.String());
@@ -19,7 +19,7 @@
#include "GradientTransformable.h"
#include "Icon.h"
#include "PathContainer.h"
#include "Shape.h"
#include "PathSourceShape.h"
#include "ShapeContainer.h"
#include "StrokeTransformer.h"
#include "Style.h"
@@ -112,9 +112,12 @@ printf("scale: %f\n", scale);
// clean up styles and paths (remove duplicates)
int32 count = icon->Shapes()->CountShapes();
for (int32 i = 1; i < count; i++) {
Shape* shape = icon->Shapes()->ShapeAtFast(i);
PathSourceShape* shape = dynamic_cast<PathSourceShape*>(icon->Shapes()->ShapeAtFast(i));
if (shape == NULL)
continue;
Style* style = shape->Style();
if (!style)
if (style == NULL)
continue;
int32 styleIndex = icon->Styles()->IndexOf(style);
for (int32 j = 0; j < styleIndex; j++) {
@@ -134,7 +137,7 @@ printf("scale: %f\n", scale);
// AddVertexSource
status_t
AddPathsFromVertexSource(Icon* icon, Shape* shape, NSVGshape* svgShape)
AddPathsFromVertexSource(Icon* icon, PathSourceShape* shape, NSVGshape* svgShape)
{
//printf("AddPathsFromVertexSource(pathID = %ld)\n", index);
@@ -194,7 +197,7 @@ status_t
DocumentBuilder::_AddShape(NSVGshape* svgShape, bool outline,
const Transformable& transform, Icon* icon)
{
Shape* shape = new (nothrow) Shape(NULL);
PathSourceShape* shape = new (nothrow) PathSourceShape(NULL);
if (!shape || !icon->Shapes()->AddShape(shape)) {
delete shape;
return B_NO_MEMORY;
@@ -245,7 +248,7 @@ DocumentBuilder::_AddShape(NSVGshape* svgShape, bool outline,
}
} else {
paint = &svgShape->fill;
#if 0 // FIXME filling rule are missing from Shape class
#if 0 // FIXME filling rule are missing from PathSourceShape class
if (svgShape->fillRule == NSVG_FILLRULE_EVENODD)
shape->SetFillingRule(FILL_MODE_EVEN_ODD);
else
@@ -1,9 +1,10 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include <stdio.h>
@@ -19,6 +20,7 @@
#include "Icon.h"
#include "GradientTransformable.h"
#include "PathSourceShape.h"
#include "Shape.h"
#include "StrokeTransformer.h"
#include "Style.h"
@@ -200,14 +202,19 @@ convert_cap_mode_svg(agg::line_cap_e mode)
status_t
SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
{
if (shape->MaxVisibilityScale() < 1.0
|| shape->MinVisibilityScale() > 1.0) {
if (!shape->Visible(1.0)) {
// don't export shapes which are not visible at the
// default scale
return B_OK;
}
const Style* style = shape->Style();
// only render PathSourceShapes
const PathSourceShape* pathSourceShape = dynamic_cast<const PathSourceShape*>(shape);
if (pathSourceShape == NULL)
return B_OK;
const Style* style = pathSourceShape->Style();
char color[64];
status_t ret = _GetFill(style, color, stream);
@@ -230,7 +237,7 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
// hack to see if this is an outline shape
StrokeTransformer* stroke
= dynamic_cast<StrokeTransformer*>(shape->TransformerAt(0));
= dynamic_cast<StrokeTransformer*>(pathSourceShape->TransformerAt(0));
if (stroke) {
helper << "style=\"fill:none; stroke:" << color;
if (!style->Gradient() && style->Color().alpha < 255) {
@@ -259,8 +266,8 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
append_float(helper, style->Color().alpha / 255.0);
}
// if (shape->FillingRule() == FILL_MODE_EVEN_ODD &&
// shape->Paths()->CountPaths() > 1)
// if (pathSourceShape->FillingRule() == FILL_MODE_EVEN_ODD &&
// pathSourceShape->Paths()->CountPaths() > 1)
// helper << "; fill-rule:evenodd";
helper << "\"\n";
@@ -272,9 +279,9 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
if (ret < B_OK)
return ret;
int32 count = shape->Paths()->CountPaths();
int32 count = pathSourceShape->Paths()->CountPaths();
for (int32 i = 0; i < count; i++) {
VectorPath* path = shape->Paths()->PathAtFast(i);
VectorPath* path = pathSourceShape->Paths()->PathAtFast(i);
if (i > 0) {
helper << "\n ";
@@ -340,9 +347,9 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
}
helper << "\"\n";
if (!shape->IsIdentity()) {
if (!pathSourceShape->IsIdentity()) {
helper << " transform=\"";
_AppendMatrix(shape, helper);
_AppendMatrix(pathSourceShape, helper);
helper << "\n";
}
@@ -16,7 +16,7 @@
#include <Locale.h>
#include "GradientTransformable.h"
#include "Shape.h"
#include "PathSourceShape.h"
#include "Style.h"
#include "VectorPath.h"
@@ -29,10 +29,10 @@ using std::nothrow;
// constructor
FreezeTransformationCommand::FreezeTransformationCommand(
Shape** const shapes,
PathSourceShape** const shapes,
int32 count)
: Command(),
fShapes(shapes && count > 0 ? new (nothrow) Shape*[count] : NULL),
fShapes(shapes && count > 0 ? new (nothrow) PathSourceShape*[count] : NULL),
fOriginalTransformations(count > 0 ? new (nothrow) double[
count * Transformable::matrix_size]
: NULL),
@@ -41,7 +41,7 @@ FreezeTransformationCommand::FreezeTransformationCommand(
if (!fShapes || !fOriginalTransformations)
return;
memcpy(fShapes, shapes, sizeof(Shape*) * fCount);
memcpy(fShapes, shapes, sizeof(PathSourceShape*) * fCount);
bool initOk = false;
@@ -128,7 +128,7 @@ FreezeTransformationCommand::GetName(BString& name)
// _ApplyTransformation
void
FreezeTransformationCommand::_ApplyTransformation(Shape* shape,
FreezeTransformationCommand::_ApplyTransformation(PathSourceShape* shape,
const Transformable& transform)
{
// apply inverse of old shape transformation to every assigned path
@@ -14,7 +14,7 @@
_BEGIN_ICON_NAMESPACE
class Shape;
class PathSourceShape;
class Transformable;
_END_ICON_NAMESPACE
@@ -24,7 +24,7 @@ _USING_ICON_NAMESPACE
class FreezeTransformationCommand : public Command {
public:
FreezeTransformationCommand(
Shape** const shapes,
PathSourceShape** const shapes,
int32 count);
virtual ~FreezeTransformationCommand();
@@ -36,10 +36,10 @@ class FreezeTransformationCommand : public Command {
virtual void GetName(BString& name);
private:
void _ApplyTransformation(Shape* shape,
void _ApplyTransformation(PathSourceShape* shape,
const Transformable& transform);
Shape** fShapes;
PathSourceShape** fShapes;
double* fOriginalTransformations;
int32 fCount;
};
@@ -15,6 +15,7 @@
#include <Locale.h>
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "Shape.h"
#include "VectorPath.h"
@@ -44,7 +45,8 @@ RemovePathsCommand::RemovePathsCommand(PathContainer* container,
if (paths[i]) {
int32 listenerCount = paths[i]->CountListeners();
for (int32 j = 0; j < listenerCount; j++) {
Shape* shape = dynamic_cast<Shape*>(paths[i]->ListenerAtFast(j));
PathSourceShape* shape
= dynamic_cast<PathSourceShape*>(paths[i]->ListenerAtFast(j));
if (shape)
fInfos[i].shapes.AddItem((void*)shape);
}
@@ -82,7 +84,7 @@ RemovePathsCommand::Perform()
fContainer->RemovePath(fInfos[i].path);
int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) {
Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
shape->Paths()->RemovePath(fInfos[i].path);
}
}
@@ -108,7 +110,7 @@ RemovePathsCommand::Undo()
fContainer->RemovePath(fInfos[j].path);
int32 shapeCount = fInfos[j].shapes.CountItems();
for (int32 k = 0; k < shapeCount; k++) {
Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k);
PathSourceShape* shape = (PathSourceShape*)fInfos[j].shapes.ItemAtFast(k);
shape->Paths()->RemovePath(fInfos[j].path);
}
}
@@ -116,7 +118,7 @@ RemovePathsCommand::Undo()
}
int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) {
Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
shape->Paths()->AddPath(fInfos[i].path);
}
}
@@ -12,7 +12,7 @@
#include <Locale.h>
#include "PathContainer.h"
#include "Shape.h"
#include "PathSourceShape.h"
#include "VectorPath.h"
@@ -21,7 +21,7 @@
// constructor
UnassignPathCommand::UnassignPathCommand(Shape* shape,
UnassignPathCommand::UnassignPathCommand(PathSourceShape* shape,
VectorPath* path)
: Command(),
fShape(shape),
@@ -14,7 +14,7 @@
_BEGIN_ICON_NAMESPACE
class Shape;
class PathSourceShape;
class VectorPath;
_END_ICON_NAMESPACE
@@ -23,7 +23,7 @@ _USING_ICON_NAMESPACE
class UnassignPathCommand : public Command {
public:
UnassignPathCommand(Shape* shape,
UnassignPathCommand(PathSourceShape* shape,
VectorPath* path);
virtual ~UnassignPathCommand();
@@ -35,7 +35,7 @@ class UnassignPathCommand : public Command {
virtual void GetName(BString& name);
private:
Shape* fShape;
PathSourceShape* fShape;
VectorPath* fPath;
bool fPathRemoved;
};
@@ -11,6 +11,7 @@
#include <Catalog.h>
#include <Locale.h>
#include "PathSourceShape.h"
#include "Shape.h"
#include "Style.h"
@@ -20,7 +21,7 @@
// constructor
AssignStyleCommand::AssignStyleCommand(Shape* shape,
AssignStyleCommand::AssignStyleCommand(PathSourceShape* shape,
Style* style)
: Command(),
fShape(shape),
@@ -16,7 +16,7 @@
_BEGIN_ICON_NAMESPACE
class Shape;
class PathSourceShape;
class Style;
_END_ICON_NAMESPACE
@@ -25,7 +25,7 @@ _USING_ICON_NAMESPACE
class AssignStyleCommand : public Command {
public:
AssignStyleCommand(Shape* shape,
AssignStyleCommand(PathSourceShape* shape,
Style* style);
virtual ~AssignStyleCommand();
@@ -37,7 +37,7 @@ class AssignStyleCommand : public Command {
virtual void GetName(BString& name);
private:
Shape* fShape;
PathSourceShape* fShape;
Style* fOldStyle;
Style* fNewStyle;
};
@@ -14,8 +14,8 @@
#include <Catalog.h>
#include <Locale.h>
#include "PathSourceShape.h"
#include "StyleContainer.h"
#include "Shape.h"
#include "Style.h"
@@ -44,8 +44,9 @@ RemoveStylesCommand::RemoveStylesCommand(StyleContainer* container,
if (styles[i]) {
int32 listenerCount = styles[i]->CountObservers();
for (int32 j = 0; j < listenerCount; j++) {
Shape* shape = dynamic_cast<Shape*>(styles[i]->ObserverAtFast(j));
if (shape)
PathSourceShape* shape
= dynamic_cast<PathSourceShape*>(styles[i]->ObserverAtFast(j));
if (shape != NULL)
fInfos[i].shapes.AddItem((void*)shape);
}
}
@@ -88,7 +89,7 @@ RemoveStylesCommand::Perform()
continue;
int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) {
Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
shape->SetStyle(fContainer->StyleAt(0));
}
}
@@ -117,7 +118,7 @@ RemoveStylesCommand::Undo()
for (int32 j = i - 1; j >= 0; j--) {
int32 shapeCount = fInfos[j].shapes.CountItems();
for (int32 k = 0; k < shapeCount; k++) {
Shape* shape = (Shape*)fInfos[j].shapes.ItemAtFast(k);
PathSourceShape* shape = (PathSourceShape*)fInfos[j].shapes.ItemAtFast(k);
shape->SetStyle(fContainer->StyleAt(0));
}
}
@@ -125,7 +126,7 @@ RemoveStylesCommand::Undo()
}
int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) {
Shape* shape = (Shape*)fInfos[i].shapes.ItemAtFast(j);
PathSourceShape* shape = (PathSourceShape*)fInfos[i].shapes.ItemAtFast(j);
shape->SetStyle(fInfos[i].style);
}
}
+2
View File
@@ -38,6 +38,8 @@ BuildPlatformMergeObjectPIC <libbe_build>icon_kit.o :
# shape
PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp
ShapeContainer.cpp
VectorPath.cpp
+2
View File
@@ -36,6 +36,8 @@ BuildPlatformStaticLibrary libicon_build.a :
# shape
PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp
ShapeContainer.cpp
VectorPath.cpp
+30 -20
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006, Haiku.
* Copyright 2006, 2023, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "Icon.h"
@@ -12,6 +13,8 @@
#include <stdio.h>
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h"
#include "Style.h"
#include "StyleContainer.h"
@@ -79,30 +82,37 @@ Icon::Icon(const Icon& other)
int32 shapeCount = other.fShapes->CountShapes();
for (int32 i = 0; i < shapeCount; i++) {
Shape* shape = other.fShapes->ShapeAtFast(i);
Shape* clone = new (nothrow) Shape(*shape);
Shape* clone = shape->Clone();
if (!clone || !fShapes->AddShape(clone)) {
delete clone;
return;
}
// the cloned shape references styles and paths in
// the "other" icon, replace them with "local" styles
// and paths
int32 styleIndex = other.fStyles->IndexOf(shape->Style());
clone->SetStyle(fStyles->StyleAt(styleIndex));
clone->Paths()->MakeEmpty();
pathCount = shape->Paths()->CountPaths();
for (int32 j = 0; j < pathCount; j++) {
VectorPath* remote = shape->Paths()->PathAtFast(j);
int32 index = other.fPaths->IndexOf(remote);
VectorPath* local = fPaths->PathAt(index);
if (!local) {
printf("failed to match remote and "
"local paths while cloning icon\n");
continue;
}
if (!clone->Paths()->AddPath(local)) {
return;
// PathSourceShapes require further handling
PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(shape);
PathSourceShape* pathSourceShapeClone = dynamic_cast<PathSourceShape*>(clone);
if (pathSourceShape != NULL && pathSourceShapeClone != NULL) {
// the cloned shape references styles and paths in
// the "other" icon, replace them with "local" styles
// and paths
int32 styleIndex = other.fStyles->IndexOf(pathSourceShape->Style());
pathSourceShapeClone->SetStyle(fStyles->StyleAt(styleIndex));
pathSourceShapeClone->Paths()->MakeEmpty();
pathCount = pathSourceShape->Paths()->CountPaths();
for (int32 j = 0; j < pathCount; j++) {
VectorPath* remote = pathSourceShape->Paths()->PathAtFast(j);
int32 index = other.fPaths->IndexOf(remote);
VectorPath* local = fPaths->PathAt(index);
if (!local) {
printf("failed to match remote and "
"local paths while cloning icon\n");
continue;
}
if (!pathSourceShapeClone->Paths()->AddPath(local)) {
return;
}
}
}
}
+141 -27
View File
@@ -1,19 +1,23 @@
/*
* Copyright 2006-2007, Haiku. All rights reserved.
* Copyright 2006-2007, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "IconRenderer.h"
#include <algorithm>
#include <new>
#include <stdio.h>
#include <Bitmap.h>
#include <List.h>
#include <agg_image_accessors.h>
#include <agg_span_image_filter_rgba.h>
#include <agg_span_gradient.h>
#include <agg_span_interpolator_linear.h>
@@ -33,12 +37,22 @@ class IconRenderer::StyleHandler {
};
public:
#ifdef ICON_O_MATIC
StyleHandler(::GammaTable& gammaTable, bool showReferences)
: fStyles(20),
fGammaTable(gammaTable),
fShowReferences(showReferences),
fTransparent(0, 0, 0, 0),
fColor(0, 0, 0, 0)
{}
#else
StyleHandler(::GammaTable& gammaTable)
: fStyles(20),
fGammaTable(gammaTable),
fTransparent(0, 0, 0, 0),
fColor(0, 0, 0, 0)
{}
#endif // ICON_O_MATIC
~StyleHandler()
{
@@ -53,7 +67,15 @@ class IconRenderer::StyleHandler {
if (!styleItem)
return true;
return styleItem->style->Gradient() == NULL;
if (styleItem->style->Gradient())
return false;
#ifdef ICON_O_MATIC
if (styleItem->style->Bitmap() && fShowReferences)
return false;
#endif // ICON_O_MATIC
return true;
}
const agg::rgba8& color(unsigned styleIndex);
@@ -86,14 +108,21 @@ private:
void _GenerateGradient(agg::rgba8* span, int x, int y, unsigned len,
GradientFunction function, int32 start, int32 end,
const agg::rgba8* gradientColors, Transformation& gradientTransform);
#ifdef ICON_O_MATIC
void _GenerateImage(agg::rgba8* span, int x, int y,
unsigned len, Style* style, Transformation& transform);
#endif
BList fStyles;
::GammaTable& fGammaTable;
#ifdef ICON_O_MATIC
bool fShowReferences;
#endif
agg::rgba8 fTransparent;
agg::rgba8 fColor;
};
// color
const agg::rgba8&
IconRenderer::StyleHandler::color(unsigned styleIndex)
{
@@ -103,6 +132,13 @@ IconRenderer::StyleHandler::color(unsigned styleIndex)
return fTransparent;
}
#ifdef ICON_O_MATIC
if (styleItem->style->Bitmap() && !fShowReferences) {
fColor = agg::rgba8(0,0,0,0);
return fColor;
}
#endif
const rgb_color& c = styleItem->style->Color();
fColor = agg::rgba8(fGammaTable.dir(c.red), fGammaTable.dir(c.green),
fGammaTable.dir(c.blue), c.alpha);
@@ -110,18 +146,30 @@ IconRenderer::StyleHandler::color(unsigned styleIndex)
return fColor;
}
// generate_span
void
IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
unsigned len, unsigned styleIndex)
{
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex);
if (!styleItem || !styleItem->style->Gradient()) {
if (!styleItem
|| (!styleItem->style->Gradient()
#ifdef ICON_O_MATIC
&& !styleItem->style->Bitmap()
#endif
)) {
printf("no style/gradient at index: %u!\n", styleIndex);
// TODO: memset() span?
return;
}
#ifdef ICON_O_MATIC
if (styleItem->style->Bitmap()) {
_GenerateImage(span, x, y, len, styleItem->style, styleItem->transformation);
return;
}
#endif // ICON_O_MATIC
Style* style = styleItem->style;
Gradient* gradient = style->Gradient();
const agg::rgba8* colors = style->GammaCorrectedColors(fGammaTable);
@@ -166,7 +214,7 @@ IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
}
}
// _GenerateGradient
template<class GradientFunction>
void
IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y,
@@ -189,8 +237,51 @@ IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y,
gradientGenerator.generate(span, x, y, len);
}
#ifdef ICON_O_MATIC
void
IconRenderer::StyleHandler::_GenerateImage(agg::rgba8* span, int x, int y,
unsigned len, Style* style, Transformation& transform)
{
// bitmap
BBitmap* bbitmap = style->Bitmap();
agg::rendering_buffer bitmap;
bitmap.attach(static_cast<unsigned char*>(bbitmap->Bits()), bbitmap->Bounds().Width() + 1,
bbitmap->Bounds().Height() + 1, bbitmap->BytesPerRow());
// pixel format attached to bitmap
PixelFormat pixf_img(bitmap);
// image interpolator
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(transform);
// image accessor attached to pixel format of bitmap
typedef agg::image_accessor_wrap<PixelFormat,
agg::wrap_mode_repeat, agg::wrap_mode_repeat> source_type;
source_type source(pixf_img);
// image filter (nearest neighbor)
typedef agg::span_image_filter_rgba_nn<
source_type, interpolator_type> span_gen_type;
span_gen_type spanGenerator(source, interpolator);
// generate the requested span
spanGenerator.generate(span, x, y, len);
// apply postprocessing
for (unsigned i = 0; i < len; i++) {
span[i].apply_gamma_dir(fGammaTable);
span[i].a = (uint8) ((float) span[i].a * style->Alpha() / 255);
span[i].premultiply();
}
}
#endif // ICON_O_MATIC
// #pragma mark -
class HintingTransformer {
public:
@@ -204,7 +295,7 @@ class HintingTransformer {
// #pragma mark -
// constructor
IconRenderer::IconRenderer(BBitmap* bitmap)
: fBitmap(bitmap),
fBackground(NULL),
@@ -236,12 +327,12 @@ IconRenderer::IconRenderer(BBitmap* bitmap)
bitmap->Bounds().IntegerHeight());
}
// destructor
IconRenderer::~IconRenderer()
{
}
// SetIcon
void
IconRenderer::SetIcon(const Icon* icon)
{
@@ -252,21 +343,37 @@ IconRenderer::SetIcon(const Icon* icon)
// TODO: ... ?
}
// Render
void
#ifdef ICON_O_MATIC
IconRenderer::Render(bool showReferences)
#else
IconRenderer::Render()
#endif
{
#ifdef ICON_O_MATIC
_Render(fBitmap->Bounds(), showReferences);
#else
_Render(fBitmap->Bounds());
#endif
}
// Render
void
#ifdef ICON_O_MATIC
IconRenderer::Render(const BRect& area, bool showReferences)
#else
IconRenderer::Render(const BRect& area)
#endif
{
#ifdef ICON_O_MATIC
_Render(fBitmap->Bounds() & area, showReferences);
#else
_Render(fBitmap->Bounds() & area);
#endif
}
//SetScale
void
IconRenderer::SetScale(double scale)
{
@@ -274,14 +381,14 @@ IconRenderer::SetScale(double scale)
fGlobalTransform.multiply(agg::trans_affine_scaling(scale));
}
//SetBackground
void
IconRenderer::SetBackground(const BBitmap* background)
{
fBackground = background;
}
//SetBackground
void
IconRenderer::SetBackground(const agg::rgba8& background)
{
@@ -291,7 +398,7 @@ IconRenderer::SetBackground(const agg::rgba8& background)
fBackgroundColor.a = background.a;
}
// Demultiply
void
IconRenderer::Demultiply()
{
@@ -314,14 +421,20 @@ IconRenderer::Demultiply()
}
}
// #pragma mark -
typedef agg::conv_transform<VertexSource, Transformation> ScaledPath;
typedef agg::conv_transform<ScaledPath, HintingTransformer> HintedPath;
// _Render
void
#ifdef ICON_O_MATIC
IconRenderer::_Render(const BRect& r, bool showReferences)
#else
IconRenderer::_Render(const BRect& r)
#endif
{
if (!fIcon)
return;
@@ -336,7 +449,11 @@ IconRenderer::_Render(const BRect& r)
fBaseRendererPre.clear(fBackgroundColor);
//bigtime_t start = system_time();
#ifdef ICON_O_MATIC
StyleHandler styleHandler(fGammaTable, showReferences);
#else
StyleHandler styleHandler(fGammaTable);
#endif
fRasterizer.reset();
// iterate over the shapes in the icon,
@@ -347,12 +464,7 @@ IconRenderer::_Render(const BRect& r)
for (int32 i = 0; i < shapeCount; i++) {
Shape* shape = fIcon->Shapes()->ShapeAtFast(i);
// Don't render shape if the Level Of Detail falls out of range.
// That's unless the scale is bigger than the maximum
// MaxVisibilityScale of 4.0f.
if (fGlobalTransform.scale() < shape->MinVisibilityScale()
|| (fGlobalTransform.scale() > shape->MaxVisibilityScale()
&& shape->MaxVisibilityScale() < 4.0f)) {
if (!shape->Visible(fGlobalTransform.scale())) {
continue;
}
@@ -385,7 +497,12 @@ IconRenderer::_Render(const BRect& r)
// if this is not the first shape, and the style contains
// transparency, commit a render pass of previous shapes
if (i > 0 && style->HasTransparency())
if (i > 0
&& (style->HasTransparency()
#ifdef ICON_O_MATIC
|| style->Bitmap() != NULL
#endif
))
_CommitRenderPass(styleHandler);
fRasterizer.styles(styleIndex, -1);
@@ -413,7 +530,7 @@ IconRenderer::_Render(const BRect& r)
//printf("rendering 64x64: %lld\n", system_time() - start);
}
// _CommitRenderPass
void
IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset)
{
@@ -424,6 +541,3 @@ IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset)
fRasterizer.reset();
}
+11 -1
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006-2007, Haiku.
* Copyright 2006-2007, 2023, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifndef ICON_RENDERER_H
#define ICON_RENDERER_H
@@ -55,8 +56,13 @@ class IconRenderer {
void SetIcon(const Icon* icon);
#ifdef ICON_O_MATIC
void Render(bool showReferences);
void Render(const BRect& area, bool showReferences);
#else
void Render();
void Render(const BRect& area);
#endif // ICON_O_MATIC
void SetScale(double scale);
void SetBackground(const BBitmap* background);
@@ -77,7 +83,11 @@ class IconRenderer {
private:
class StyleHandler;
#ifdef ICON_O_MATIC
void _Render(const BRect& area, bool showReferences);
#else
void _Render(const BRect& area);
#endif // ICON_O_MATIC
void _CommitRenderPass(StyleHandler& styleHandler,
bool reset = true);
+2
View File
@@ -45,6 +45,8 @@ for architectureObject in [ MultiArchSubDirSetup ] {
# shape
PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp
ShapeContainer.cpp
VectorPath.cpp
+2 -1
View File
@@ -24,6 +24,7 @@
#include "LittleEndianBuffer.h"
#include "PathCommandQueue.h"
#include "PathContainer.h"
#include "PathSourceShape.h"
#include "PerspectiveTransformer.h"
#include "Shape.h"
#include "StrokeTransformer.h"
@@ -543,7 +544,7 @@ FlatIconImporter::_ReadPathSourceShape(LittleEndianBuffer& buffer,
}
// create the shape
Shape* shape = new (nothrow) Shape(style);
PathSourceShape* shape = new (nothrow) PathSourceShape(style);
ObjectDeleter<Shape> shapeDeleter(shape);
if (!shape || shape->InitCheck() < B_OK)
+70 -46
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006-2010, Haiku. All rights reserved.
* Copyright 2006-2010, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
@@ -13,6 +14,9 @@
#include <stdio.h>
#include <Archivable.h>
#ifdef ICON_O_MATIC
#include <Bitmap.h>
#endif
#include <ByteOrder.h>
#include <DataIO.h>
#include <Message.h>
@@ -20,6 +24,10 @@
#include "Defines.h"
#include "Icon.h"
#include "PathContainer.h"
#include "PathSourceShape.h"
#ifdef ICON_O_MATIC
#include "ReferenceImage.h"
#endif
#include "Shape.h"
#include "Style.h"
#include "StyleContainer.h"
@@ -178,56 +186,72 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
BMessage shapeArchive;
for (int32 i = 0;
allShapes.FindMessage("shape", i, &shapeArchive) == B_OK; i++) {
// find the right style
int32 styleIndex;
if (shapeArchive.FindInt32("style ref", &styleIndex) < B_OK) {
printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " doesn't reference a Style!", i);
continue;
}
#ifdef ICON_O_MATIC
Style* style = styles->StyleAt(StyleIndexFor(styleIndex));
#else
Style* style = styles->StyleAt(styleIndex);
#endif
if (!style) {
printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " wants Style %" B_PRId32 ", which does not exist\n",
i, styleIndex);
continue;
}
int32 type;
status_t typeFound = shapeArchive.FindInt32("type", &type);
if (typeFound != B_OK || type == PathSourceShape::archive_code) {
// Type not being found shows an older format that did not support
// reference images
// create shape
Shape* shape = new (nothrow) Shape(style);
if (!shape || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) {
delete shape;
ret = B_NO_MEMORY;
}
if (ret < B_OK)
break;
// find the referenced paths
int32 pathIndex;
for (int32 j = 0;
shapeArchive.FindInt32("path ref", j, &pathIndex) == B_OK;
j++) {
#ifdef ICON_O_MATIC
VectorPath* path = paths->PathAt(PathIndexFor(pathIndex));
#else
VectorPath* path = paths->PathAt(pathIndex);
#endif
if (!path) {
// find the right style
int32 styleIndex;
if (shapeArchive.FindInt32("style ref", &styleIndex) < B_OK) {
printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " referenced path %" B_PRId32 ", "
"which does not exist\n", i, pathIndex);
"Shape %" B_PRId32 " doesn't reference a Style!", i);
continue;
}
#ifdef ICON_O_MATIC
Style* style = styles->StyleAt(StyleIndexFor(styleIndex));
#else
Style* style = styles->StyleAt(styleIndex);
#endif
if (style == NULL) {
printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " wants Style %" B_PRId32 ", which does not exist\n",
i, styleIndex);
continue;
}
shape->Paths()->AddPath(path);
}
// Shape properties
if (ret == B_OK)
shape->Unarchive(&shapeArchive);
// create shape
PathSourceShape* shape = new (nothrow) PathSourceShape(style);
if (shape == NULL || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) {
delete shape;
ret = B_NO_MEMORY;
}
if (ret < B_OK)
break;
// find the referenced paths
int32 pathIndex;
for (int32 j = 0;
shapeArchive.FindInt32("path ref", j, &pathIndex) == B_OK;
j++) {
#ifdef ICON_O_MATIC
VectorPath* path = paths->PathAt(PathIndexFor(pathIndex));
#else
VectorPath* path = paths->PathAt(pathIndex);
#endif
if (path == NULL) {
printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " referenced path %" B_PRId32 ", "
"which does not exist\n", i, pathIndex);
continue;
}
shape->Paths()->AddPath(path);
}
// Shape properties
if (ret == B_OK)
shape->Unarchive(&shapeArchive);
}
#ifdef ICON_O_MATIC
else if (type == ReferenceImage::archive_code) {
ReferenceImage* shape = new (nothrow) ReferenceImage(&shapeArchive);
if (shape == NULL || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) {
delete shape;
ret = B_NO_MEMORY;
}
}
#endif // ICON_O_MATIC
}
return ret;
+177
View File
@@ -0,0 +1,177 @@
/*
* Copyright 2006, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "PathSourceShape.h"
#include <new>
#include <agg_bounding_rect.h>
#include <Message.h>
#ifdef ICON_O_MATIC
# include "CommonPropertyIDs.h"
# include "Property.h"
# include "PropertyObject.h"
#endif // ICON_O_MATIC
#include "Style.h"
using std::nothrow;
PathSourceShape::PathSourceShape(::Style* style)
: Shape(style),
fMinVisibilityScale(0.0),
fMaxVisibilityScale(4.0)
{
}
PathSourceShape::PathSourceShape(const PathSourceShape& other)
: Shape(other),
fMinVisibilityScale(other.fMinVisibilityScale),
fMaxVisibilityScale(other.fMaxVisibilityScale)
{
}
PathSourceShape::~PathSourceShape()
{
}
// #pragma mark -
status_t
PathSourceShape::Unarchive(BMessage* archive)
{
Shape::Unarchive(archive);
// min visibility scale
if (archive->FindFloat("min visibility scale", &fMinVisibilityScale) < B_OK)
fMinVisibilityScale = 0.0;
// max visibility scale
if (archive->FindFloat("max visibility scale", &fMaxVisibilityScale) < B_OK)
fMaxVisibilityScale = 4.0;
if (fMinVisibilityScale < 0.0)
fMinVisibilityScale = 0.0;
if (fMinVisibilityScale > 4.0)
fMinVisibilityScale = 4.0;
if (fMaxVisibilityScale < 0.0)
fMaxVisibilityScale = 0.0;
if (fMaxVisibilityScale > 4.0)
fMaxVisibilityScale = 4.0;
return B_OK;
}
#ifdef ICON_O_MATIC
status_t
PathSourceShape::Archive(BMessage* into, bool deep) const
{
status_t ret = Shape::Archive(into, deep);
// min visibility scale
if (ret == B_OK)
ret = into->AddFloat("min visibility scale", fMinVisibilityScale);
// max visibility scale
if (ret == B_OK)
ret = into->AddFloat("max visibility scale", fMaxVisibilityScale);
return ret;
}
PropertyObject*
PathSourceShape::MakePropertyObject() const
{
PropertyObject* object = Shape::MakePropertyObject();
if (object == NULL)
return NULL;
// object->AddProperty(new BoolProperty(PROPERTY_HINTING, fHinting));
object->AddProperty(new FloatProperty(PROPERTY_MIN_VISIBILITY_SCALE,
fMinVisibilityScale, 0, 4));
object->AddProperty(new FloatProperty(PROPERTY_MAX_VISIBILITY_SCALE,
fMaxVisibilityScale, 0, 4));
return object;
}
bool
PathSourceShape::SetToPropertyObject(const PropertyObject* object)
{
AutoNotificationSuspender _(this);
Shape::SetToPropertyObject(object);
// hinting
// SetHinting(object->Value(PROPERTY_HINTING, fHinting));
// min visibility scale
SetMinVisibilityScale(object->Value(PROPERTY_MIN_VISIBILITY_SCALE, fMinVisibilityScale));
// max visibility scale
SetMaxVisibilityScale(object->Value(PROPERTY_MAX_VISIBILITY_SCALE, fMaxVisibilityScale));
return HasPendingNotifications();
}
#endif // ICON_O_MATIC
// #pragma mark -
status_t
PathSourceShape::InitCheck() const
{
return Shape::InitCheck();
}
// #pragma mark -
void
PathSourceShape::SetMinVisibilityScale(float scale)
{
if (fMinVisibilityScale == scale)
return;
fMinVisibilityScale = scale;
Notify();
}
void
PathSourceShape::SetMaxVisibilityScale(float scale)
{
if (fMaxVisibilityScale == scale)
return;
fMaxVisibilityScale = scale;
Notify();
}
bool
PathSourceShape::Visible(float scale) const
{
return scale >= MinVisibilityScale()
&& (scale <= MaxVisibilityScale() || MaxVisibilityScale() >= 4.0f);
}
+79
View File
@@ -0,0 +1,79 @@
/*
* Copyright 2006-2007, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifndef PATH_SOURCE_SHAPE_H
#define PATH_SOURCE_SHAPE_H
#include "IconBuild.h"
#include "Shape.h"
class BMessage;
_BEGIN_ICON_NAMESPACE
class PathContainer;
class PropertyObject;
class Style;
class PathSourceShape : public _ICON_NAMESPACE Shape {
public:
enum {
archive_code = 'shps'
};
PathSourceShape(::Style* style);
PathSourceShape(const PathSourceShape& other);
virtual ~PathSourceShape();
// IconObject interface
virtual status_t Unarchive(BMessage* archive);
#ifdef ICON_O_MATIC
virtual status_t Archive(BMessage* into,
bool deep = true) const;
virtual PropertyObject* MakePropertyObject() const;
virtual bool SetToPropertyObject(
const PropertyObject* object);
#else
inline void Notify() {}
#endif // ICON_O_MATIC
// PathSourceShape
virtual status_t InitCheck() const;
virtual PathSourceShape* Clone() const
{ return new PathSourceShape(*this); }
void SetStyle(::Style* style)
{ Shape::SetStyle(style); }
inline ::Style* Style() const
{ return Shape::Style(); }
void SetMinVisibilityScale(float scale);
float MinVisibilityScale() const
{ return fMinVisibilityScale; }
void SetMaxVisibilityScale(float scale);
float MaxVisibilityScale() const
{ return fMaxVisibilityScale; }
virtual bool Visible(float scale) const;
private:
float fMinVisibilityScale;
float fMaxVisibilityScale;
};
_END_ICON_NAMESPACE
#endif // PATH_SOURCE_SHAPE_H
+210
View File
@@ -0,0 +1,210 @@
/*
* 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();
// The shape constructor acquired a reference
SetName("<reference image>");
SetImage(image);
double width = (int) Style()->Bitmap()->Bounds().Width() + 1;
double height = (int) Style()->Bitmap()->Bounds().Height() + 1;
// Scale to fill canvas
double longerSide = std::max(width, height);
ScaleBy(BPoint(0, 0), 64/longerSide, 64/longerSide);
// Center
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();
// The shape constructor acquired a reference
BBitmap* bitmap = new (nothrow) BBitmap(other.Style()->Bitmap());
if (bitmap == NULL)
return;
SetName(other.Name());
SetImage(bitmap);
SetTransform(other);
}
ReferenceImage::ReferenceImage(BMessage* archive)
: Shape(new (nothrow) _ICON_NAMESPACE Style()),
fPath(NULL)
{
Unarchive(archive);
}
ReferenceImage::~ReferenceImage()
{
}
// #pragma mark -
status_t
ReferenceImage::Unarchive(BMessage* archive)
{
// IconObject properties
status_t ret = IconObject::Unarchive(archive);
if (ret < B_OK)
return ret;
// read transformation
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);
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;
// transformation
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;
// image
ret = Style()->Bitmap()->Archive(into, deep);
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();
}
// #pragma mark -
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;
}
// #pragma mark -
void
ReferenceImage::SetImage(BBitmap* image)
{
if (fPath != NULL) {
Paths()->MakeEmpty();
delete fPath;
fPath = NULL;
}
if (image != NULL) {
// Update style
Style()->SetBitmap(image);
// Update shape
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()->AddPath(fPath);
}
}
#endif // ICON_O_MATIC
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright 2006-2007, 2023, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifndef REFERENCE_IMAGE_H
#define REFERENCE_IMAGE_H
#ifdef ICON_O_MATIC
#include "IconObject.h"
#include "Observer.h"
#include "IconBuild.h"
#include "PathContainer.h"
#include "PathSource.h"
#include "Shape.h"
#include "Transformable.h"
#include "VectorPath.h"
#include <List.h>
#include <Rect.h>
_BEGIN_ICON_NAMESPACE
class Style;
class ReferenceImage : public _ICON_NAMESPACE Shape {
public:
enum {
archive_code = 'shri'
};
ReferenceImage(BBitmap* image);
// transfers ownership of image
ReferenceImage(const ReferenceImage& other);
ReferenceImage(BMessage* archive);
virtual ~ReferenceImage();
// IconObject interface
virtual status_t Unarchive(BMessage* archive);
virtual status_t Archive(BMessage* into,
bool deep = true) const;
virtual PropertyObject* MakePropertyObject() const;
virtual bool SetToPropertyObject(
const PropertyObject* object);
// Shape
virtual status_t InitCheck() const;
virtual Shape* Clone() const
{ return new ReferenceImage(*this); }
virtual void SetImage(BBitmap* image);
// transfers ownership of image
virtual bool Visible(float scale) const
{ return true; }
private:
VectorPath* fPath;
};
_END_ICON_NAMESPACE
#endif // ICON_O_MATIC
#endif // REFERENCE_IMAGE_H
+78 -151
View File
@@ -27,21 +27,22 @@
using std::nothrow;
#ifdef ICON_O_MATIC
// constructor
ShapeListener::ShapeListener()
{
}
// destructor
ShapeListener::~ShapeListener()
{
}
#endif // ICON_O_MATIC
// #pragma mark -
// constructor
Shape::Shape(::Style* style)
#ifdef ICON_O_MATIC
: IconObject("<shape>"),
@@ -61,9 +62,7 @@ Shape::Shape(::Style* style)
fLastBounds(0, 0, -1, -1),
fHinting(false),
fMinVisibilityScale(0.0),
fMaxVisibilityScale(4.0)
fHinting(false)
#ifdef ICON_O_MATIC
, fListeners(8)
@@ -77,7 +76,7 @@ Shape::Shape(::Style* style)
#endif
}
// constructor
Shape::Shape(const Shape& other)
#ifdef ICON_O_MATIC
: IconObject(other),
@@ -97,9 +96,7 @@ Shape::Shape(const Shape& other)
fLastBounds(0, 0, -1, -1),
fHinting(other.fHinting),
fMinVisibilityScale(other.fMinVisibilityScale),
fMaxVisibilityScale(other.fMaxVisibilityScale)
fHinting(false)
#ifdef ICON_O_MATIC
, fListeners(8)
@@ -111,6 +108,7 @@ Shape::Shape(const Shape& other)
#ifdef ICON_O_MATIC
fPaths->AddListener(this);
#endif
// copy the path references from
// the other shape
if (other.fPaths) {
@@ -133,7 +131,7 @@ Shape::Shape(const Shape& other)
}
}
// destructor
Shape::~Shape()
{
int32 count = fTransformers.CountItems();
@@ -155,11 +153,12 @@ Shape::~Shape()
SetStyle(NULL);
}
// #pragma mark -
// Unarchive
status_t
Shape::Unarchive(const BMessage* archive)
Shape::Unarchive(BMessage* archive)
{
#ifdef ICON_O_MATIC
// IconObject properties
@@ -170,11 +169,15 @@ Shape::Unarchive(const BMessage* archive)
status_t ret;
#endif
// hinting
if (archive->FindBool("hinting", &fHinting) < B_OK)
fHinting = false;
// recreate transformers
BMessage transformerArchive;
for (int32 i = 0;
archive->FindMessage("transformer", i,
&transformerArchive) == B_OK;
&transformerArchive) == B_OK;
i++) {
Transformer* transformer
= TransformerFactory::TransformerFor(
@@ -189,44 +192,24 @@ Shape::Unarchive(const BMessage* archive)
const void* matrix;
ssize_t dataSize = size * sizeof(double);
ret = archive->FindData("transformation", B_DOUBLE_TYPE,
&matrix, &dataSize);
&matrix, &dataSize);
if (ret == B_OK && dataSize == (ssize_t)(size * sizeof(double)))
LoadFrom((const double*)matrix);
// hinting
if (archive->FindBool("hinting", &fHinting) < B_OK)
fHinting = false;
// min visibility scale
if (archive->FindFloat("min visibility scale",
&fMinVisibilityScale) < B_OK)
fMinVisibilityScale = 0.0;
// max visibility scale
if (archive->FindFloat("max visibility scale",
&fMaxVisibilityScale) < B_OK)
fMaxVisibilityScale = 4.0;
if (fMinVisibilityScale < 0.0)
fMinVisibilityScale = 0.0;
if (fMinVisibilityScale > 4.0)
fMinVisibilityScale = 4.0;
if (fMaxVisibilityScale < 0.0)
fMaxVisibilityScale = 0.0;
if (fMaxVisibilityScale > 4.0)
fMaxVisibilityScale = 4.0;
return B_OK;
}
#ifdef ICON_O_MATIC
// Archive
#ifdef ICON_O_MATIC
status_t
Shape::Archive(BMessage* into, bool deep) const
{
status_t ret = IconObject::Archive(into, deep);
// hinting
if (ret == B_OK)
ret = into->AddBool("hinting", fHinting);
// transformers
if (ret == B_OK) {
int32 count = CountTransformers();
@@ -247,69 +230,32 @@ Shape::Archive(BMessage* into, bool deep) const
double matrix[size];
StoreTo(matrix);
ret = into->AddData("transformation", B_DOUBLE_TYPE,
matrix, size * sizeof(double));
matrix, size * sizeof(double));
}
// hinting
if (ret ==B_OK)
ret = into->AddBool("hinting", fHinting);
// min visibility scale
if (ret ==B_OK)
ret = into->AddFloat("min visibility scale",
fMinVisibilityScale);
// max visibility scale
if (ret ==B_OK)
ret = into->AddFloat("max visibility scale",
fMaxVisibilityScale);
return ret;
}
// MakePropertyObject
PropertyObject*
Shape::MakePropertyObject() const
{
PropertyObject* object = IconObject::MakePropertyObject();
if (!object)
return NULL;
// object->AddProperty(new BoolProperty(PROPERTY_HINTING, fHinting));
object->AddProperty(new FloatProperty(PROPERTY_MIN_VISIBILITY_SCALE,
fMinVisibilityScale, 0, 4));
object->AddProperty(new FloatProperty(PROPERTY_MAX_VISIBILITY_SCALE,
fMaxVisibilityScale, 0, 4));
return object;
}
// SetToPropertyObject
bool
Shape::SetToPropertyObject(const PropertyObject* object)
{
AutoNotificationSuspender _(this);
IconObject::SetToPropertyObject(object);
// hinting
// SetHinting(object->Value(PROPERTY_HINTING, fHinting));
// min visibility scale
SetMinVisibilityScale(object->Value(PROPERTY_MIN_VISIBILITY_SCALE,
fMinVisibilityScale));
// max visibility scale
SetMaxVisibilityScale(object->Value(PROPERTY_MAX_VISIBILITY_SCALE,
fMaxVisibilityScale));
return HasPendingNotifications();
return true;
}
// #pragma mark -
// TransformationChanged
void
Shape::TransformationChanged()
{
@@ -317,9 +263,10 @@ Shape::TransformationChanged()
_NotifyRerender();
}
// #pragma mark -
// ObjectChanged
void
Shape::ObjectChanged(const Observable* object)
{
@@ -329,9 +276,10 @@ Shape::ObjectChanged(const Observable* object)
_NotifyRerender();
}
// #pragma mark -
// PathAdded
void
Shape::PathAdded(VectorPath* path, int32 index)
{
@@ -340,7 +288,7 @@ Shape::PathAdded(VectorPath* path, int32 index)
_NotifyRerender();
}
// PathRemoved
void
Shape::PathRemoved(VectorPath* path)
{
@@ -349,65 +297,66 @@ Shape::PathRemoved(VectorPath* path)
path->ReleaseReference();
}
// #pragma mark -
// PointAdded
void
Shape::PointAdded(int32 index)
{
_NotifyRerender();
}
// PointRemoved
void
Shape::PointRemoved(int32 index)
{
_NotifyRerender();
}
// PointChanged
void
Shape::PointChanged(int32 index)
{
_NotifyRerender();
}
// PathChanged
void
Shape::PathChanged()
{
_NotifyRerender();
}
// PathClosedChanged
void
Shape::PathClosedChanged()
{
_NotifyRerender();
}
// PathReversed
void
Shape::PathReversed()
{
_NotifyRerender();
}
#endif // ICON_O_MATIC
// #pragma mark -
// InitCheck
status_t
Shape::InitCheck() const
{
return fPaths ? B_OK : B_NO_MEMORY;
}
// #pragma mark -
// SetStyle
void
Shape::SetStyle(::Style* style)
{
@@ -434,9 +383,10 @@ Shape::SetStyle(::Style* style)
#endif
}
// #pragma mark -
// Bounds
BRect
Shape::Bounds(bool updateLast) const
{
@@ -452,9 +402,9 @@ Shape::Bounds(bool updateLast) const
::VertexSource& source = const_cast<Shape*>(this)->VertexSource();
agg::conv_transform< ::VertexSource, Transformable>
transformedSource(source, *this);
transformedSource(source, *this);
agg::bounding_rect(transformedSource, pathID, 0, 1,
&left, &top, &right, &bottom);
&left, &top, &right, &bottom);
BRect bounds(left, top, right, bottom);
@@ -464,7 +414,7 @@ Shape::Bounds(bool updateLast) const
return bounds;
}
// VertexSource
::VertexSource&
Shape::VertexSource()
{
@@ -479,28 +429,28 @@ Shape::VertexSource()
if (fNeedsUpdate) {
fPathSource.Update(source->WantsOpenPaths(),
source->ApproximationScale());
source->ApproximationScale());
fNeedsUpdate = false;
}
return *source;
}
// SetGlobalScale
void
Shape::SetGlobalScale(double scale)
{
fPathSource.SetGlobalScale(scale);
}
// AddTransformer
bool
Shape::AddTransformer(Transformer* transformer)
{
return AddTransformer(transformer, CountTransformers());
}
// AddTransformer
bool
Shape::AddTransformer(Transformer* transformer, int32 index)
{
@@ -520,7 +470,7 @@ Shape::AddTransformer(Transformer* transformer, int32 index)
return true;
}
// RemoveTransformer
bool
Shape::RemoveTransformer(Transformer* transformer)
{
@@ -538,83 +488,49 @@ Shape::RemoveTransformer(Transformer* transformer)
return false;
}
// #pragma mark -
// CountShapes
int32
Shape::CountTransformers() const
{
return fTransformers.CountItems();
}
// HasTransformer
bool
Shape::HasTransformer(Transformer* transformer) const
{
return fTransformers.HasItem((void*)transformer);
}
// IndexOf
int32
Shape::IndexOf(Transformer* transformer) const
{
return fTransformers.IndexOf((void*)transformer);
}
// TransformerAt
Transformer*
Shape::TransformerAt(int32 index) const
{
return (Transformer*)fTransformers.ItemAt(index);
}
// TransformerAtFast
Transformer*
Shape::TransformerAtFast(int32 index) const
{
return (Transformer*)fTransformers.ItemAtFast(index);
}
// #pragma mark -
// SetHinting
void
Shape::SetHinting(bool hinting)
{
if (fHinting == hinting)
return;
fHinting = hinting;
Notify();
}
// SetMinVisibilityScale
void
Shape::SetMinVisibilityScale(float scale)
{
if (fMinVisibilityScale == scale)
return;
fMinVisibilityScale = scale;
Notify();
}
// SetMaxVisibilityScale
void
Shape::SetMaxVisibilityScale(float scale)
{
if (fMaxVisibilityScale == scale)
return;
fMaxVisibilityScale = scale;
Notify();
}
// #pragma mark -
#ifdef ICON_O_MATIC
// AddListener
bool
Shape::AddListener(ShapeListener* listener)
{
@@ -623,16 +539,17 @@ Shape::AddListener(ShapeListener* listener)
return false;
}
// RemoveListener
bool
Shape::RemoveListener(ShapeListener* listener)
{
return fListeners.RemoveItem((void*)listener);
}
// #pragma mark -
// _NotifyTransformerAdded
void
Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
{
@@ -647,7 +564,7 @@ Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
_NotifyRerender();
}
// _NotifyTransformerRemoved
void
Shape::_NotifyTransformerRemoved(Transformer* transformer) const
{
@@ -662,7 +579,7 @@ Shape::_NotifyTransformerRemoved(Transformer* transformer) const
_NotifyRerender();
}
// _NotifyStyleChanged
void
Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const
{
@@ -677,13 +594,23 @@ Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const
_NotifyRerender();
}
// _NotifyRerender
void
Shape::_NotifyRerender() const
{
fNeedsUpdate = true;
Notify();
}
#endif // ICON_O_MATIC
void
Shape::SetHinting(bool hinting)
{
if (fHinting == hinting)
return;
fHinting = hinting;
Notify();
}
+13 -13
View File
@@ -23,11 +23,13 @@
#include <Rect.h>
class BMessage;
_BEGIN_ICON_NAMESPACE
class Style;
#ifdef ICON_O_MATIC
// TODO: merge Observer and ShapeListener interface
// ie add "AppearanceChanged(Shape* shape)"
@@ -40,6 +42,7 @@ class ShapeListener {
int32 index) = 0;
virtual void TransformerRemoved(Transformer* t) = 0;
// TODO: this is not useful for all subclasses of Shape (e.g. ReferenceImage)
virtual void StyleChanged(::Style* oldStyle,
::Style* newStyle) = 0;
};
@@ -61,7 +64,7 @@ class Shape : public _ICON_NAMESPACE Transformable {
virtual ~Shape();
// IconObject interface
virtual status_t Unarchive(const BMessage* archive);
virtual status_t Unarchive(BMessage* archive);
#ifdef ICON_O_MATIC
virtual status_t Archive(BMessage* into,
bool deep = true) const;
@@ -92,12 +95,13 @@ class Shape : public _ICON_NAMESPACE Transformable {
#endif // ICON_O_MATIC
// Shape
status_t InitCheck() const;
virtual status_t InitCheck() const;
virtual Shape* Clone() const = 0;
inline PathContainer* Paths() const
{ return fPaths; }
void SetStyle(::Style* style);
public:
inline ::Style* Style() const
{ return fStyle; }
@@ -124,12 +128,8 @@ class Shape : public _ICON_NAMESPACE Transformable {
void SetHinting(bool hinting);
bool Hinting() const
{ return fHinting; }
void SetMinVisibilityScale(float scale);
float MinVisibilityScale() const
{ return fMinVisibilityScale; }
void SetMaxVisibilityScale(float scale);
float MaxVisibilityScale() const
{ return fMaxVisibilityScale; }
virtual bool Visible(float scale) const = 0;
#ifdef ICON_O_MATIC
bool AddListener(ShapeListener* listener);
@@ -146,6 +146,9 @@ class Shape : public _ICON_NAMESPACE Transformable {
void _NotifyRerender() const;
#endif // ICON_O_MATIC
protected:
void SetStyle(::Style* style);
private:
PathContainer* fPaths;
::Style* fStyle;
@@ -157,15 +160,12 @@ class Shape : public _ICON_NAMESPACE Transformable {
mutable BRect fLastBounds;
bool fHinting;
float fMinVisibilityScale;
float fMaxVisibilityScale;
#ifdef ICON_O_MATIC
BList fListeners;
#endif
};
_END_ICON_NAMESPACE
+79 -16
View File
@@ -1,16 +1,18 @@
/*
* Copyright 2006, Haiku.
* Copyright 2006, 2023, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#include "Style.h"
#include <new>
# include <Message.h>
#include <Bitmap.h>
#include <Message.h>
#ifdef ICON_O_MATIC
# include "ui_defines.h"
@@ -22,7 +24,7 @@
using std::nothrow;
// constructor
Style::Style()
#ifdef ICON_O_MATIC
: IconObject("<style>"),
@@ -34,13 +36,17 @@ Style::Style()
fColor(kWhite),
fGradient(NULL),
fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false)
{
}
// constructor
Style::Style(const rgb_color& color)
#ifdef ICON_O_MATIC
: IconObject("<style>"),
@@ -52,13 +58,34 @@ Style::Style(const rgb_color& color)
fColor(color),
fGradient(NULL),
fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false)
{
}
// constructor
#ifdef ICON_O_MATIC
Style::Style(BBitmap* image)
: IconObject("<style>"),
Observer(),
fColor(kWhite),
fGradient(NULL),
fColors(NULL),
fImage(image),
fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false)
{
}
#endif
Style::Style(const Style& other)
#ifdef ICON_O_MATIC
: IconObject(other),
@@ -70,6 +97,10 @@ Style::Style(const Style& other)
fColor(other.fColor),
fGradient(NULL),
fColors(NULL),
#ifdef ICON_O_MATIC
fImage(other.fImage != NULL ? new (nothrow) BBitmap(other.fImage) : NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false)
@@ -89,6 +120,10 @@ Style::Style(BMessage* archive)
fColor(kWhite),
fGradient(NULL),
fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false)
@@ -106,14 +141,18 @@ Style::Style(BMessage* archive)
}
}
// destructor
Style::~Style()
{
SetGradient(NULL);
}
#ifdef ICON_O_MATIC
// ObjectChanged
delete fImage;
#endif
}
#ifdef ICON_O_MATIC
void
Style::ObjectChanged(const Observable* object)
{
@@ -124,9 +163,10 @@ Style::ObjectChanged(const Observable* object)
}
}
// #pragma mark -
// Archive
status_t
Style::Archive(BMessage* into, bool deep) const
{
@@ -142,10 +182,12 @@ Style::Archive(BMessage* into, bool deep) const
ret = into->AddMessage("gradient", &gradientArchive);
}
// Archiving the fImage is the responsibility of ReferenceImage
return ret;
}
// operator ==
bool
Style::operator==(const Style& other) const
{
@@ -161,10 +203,9 @@ Style::operator==(const Style& other) const
return false;
}
}
#endif // ICON_O_MATIC
// HasTransparency
bool
Style::HasTransparency() const
{
@@ -180,7 +221,7 @@ Style::HasTransparency() const
return fColor.alpha < 255;
}
// SetColor
void
Style::SetColor(const rgb_color& color)
{
@@ -191,7 +232,7 @@ Style::SetColor(const rgb_color& color)
Notify();
}
// SetGradient
void
Style::SetGradient(const ::Gradient* gradient)
{
@@ -226,6 +267,9 @@ Style::SetGradient(const ::Gradient* gradient)
#ifdef ICON_O_MATIC
if (fGradient != NULL)
fGradient->ReleaseReference();
delete fImage;
fImage = NULL;
#else
delete fGradient;
#endif
@@ -236,8 +280,27 @@ Style::SetGradient(const ::Gradient* gradient)
}
}
// GammaCorrectedColors
const agg::rgba8*
#ifdef ICON_O_MATIC
void
Style::SetBitmap(BBitmap* image)
{
delete fImage;
fImage = image;
// TODO: This does not reset fGradient or fColors. Currently, this is not
// required, since Icon-O-Matic never turns Gradients into Bitmaps. Probably,
// this class should be subclassed if this feature is ever required. For more
// information, see the todo item in the header file.
if (fGradient != NULL)
debugger("Not implemented");
Notify();
}
#endif // ICON_O_MATIC
const agg::rgba8*
Style::GammaCorrectedColors(const GammaTable& table) const
{
if (!fColors)
+28 -1
View File
@@ -1,9 +1,10 @@
/*
* Copyright 2006-2007, Haiku.
* Copyright 2006-2007, 2023, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/
#ifndef STYLE_H
#define STYLE_H
@@ -30,7 +31,10 @@ _BEGIN_ICON_NAMESPACE
class Gradient;
class Shape;
// TODO: This class can represent solid colors, gradients, and bitmaps. It
// should probably be split into subclasses.
#ifdef ICON_O_MATIC
class Style : public IconObject,
public Observer {
@@ -41,6 +45,10 @@ class Style {
Style();
Style(const Style& other);
Style(const rgb_color& color);
#ifdef ICON_O_MATIC
Style(BBitmap* image);
// transfers ownership of the image
#endif
Style(BMessage* archive);
virtual ~Style();
@@ -69,6 +77,19 @@ class Style {
_ICON_NAMESPACE Gradient* Gradient() const
{ return fGradient; }
#ifdef ICON_O_MATIC
void SetBitmap(BBitmap* image);
// transfers ownership of the image
BBitmap* Bitmap() const
{ return fImage; }
// alpha only applies to bitmaps
void SetAlpha(uint8 alpha)
{ fAlpha = alpha; Notify(); }
uint8 Alpha()
{ return fAlpha; }
#endif // ICON_O_MATIC
const agg::rgba8* Colors() const
{ return fColors; }
@@ -77,11 +98,17 @@ class Style {
private:
rgb_color fColor;
_ICON_NAMESPACE Gradient* fGradient;
// hold gradient color array
agg::rgba8* fColors;
#ifdef ICON_O_MATIC
BBitmap* fImage;
uint8 fAlpha;
#endif
// for caching gamma corrected gradient color array
mutable agg::rgba8* fGammaCorrectedColors;
mutable bool fGammaCorrectedColorsValid;
@@ -16,9 +16,6 @@
#ifdef ICON_O_MATIC
#include <Catalog.h>
#include <Message.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Transformation"
#endif
@@ -30,13 +27,13 @@ Transformer*
TransformerFactory::TransformerFor(uint32 type, VertexSource& source)
{
switch (type) {
case 0:
case AFFINE_TRANSFORMER:
return new AffineTransformer(source);
case 1:
case PERSPECTIVE_TRANSFORMER:
return new PerspectiveTransformer(source);
case 2:
case CONTOUR_TRANSFORMER:
return new ContourTransformer(source);
case 3:
case STROKE_TRANSFORMER:
return new StrokeTransformer(source);
}
@@ -62,30 +59,3 @@ TransformerFactory::TransformerFor(BMessage* message,
return NULL;
}
#ifdef ICON_O_MATIC
// NextType
bool
TransformerFactory::NextType(int32* cookie, uint32* type, BString* name)
{
*type = *cookie;
*cookie = *cookie + 1;
switch (*type) {
case 0:
*name = B_TRANSLATE("Transformation");
return true;
case 1:
*name = B_TRANSLATE("Perspective");
return true;
case 2:
*name = B_TRANSLATE("Contour");
return true;
case 3:
*name = B_TRANSLATE("Stroke");
return true;
}
return false;
}
#endif // ICON_O_MATIC
@@ -23,6 +23,14 @@ _BEGIN_ICON_NAMESPACE
class Transformer;
class VertexSource;
enum {
AFFINE_TRANSFORMER,
PERSPECTIVE_TRANSFORMER,
CONTOUR_TRANSFORMER,
STROKE_TRANSFORMER,
};
class TransformerFactory {
public:
@@ -31,13 +39,6 @@ class TransformerFactory {
static Transformer* TransformerFor(BMessage* archive,
VertexSource& source);
#ifdef ICON_O_MATIC
static bool NextType(int32* cookie,
uint32* type,
BString* name);
#endif // ICON_O_MATIC
};