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) CanvasView::_DrawInto(BView* view, BRect updateRect)
{ {
if (fDirtyIconArea.IsValid()) { if (fDirtyIconArea.IsValid()) {
fRenderer->Render(fDirtyIconArea); fRenderer->Render(fDirtyIconArea, true);
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
} }
+17 -2
View File
@@ -1,6 +1,10 @@
/* /*
* Copyright 2006, 2011, Stephan Aßmus <[email protected]>. * Copyright 2006, 2011, Stephan Aßmus <[email protected]>.
* Copyright 2023 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/ */
@@ -26,6 +30,7 @@
#include "Defines.h" #include "Defines.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "SavePanel.h" #include "SavePanel.h"
#include "ShapeListView.h"
#undef B_TRANSLATION_CONTEXT #undef B_TRANSLATION_CONTEXT
@@ -123,6 +128,9 @@ IconEditorApp::MessageReceived(BMessage* message)
MainWindow* window; MainWindow* window;
if (message->FindPointer("window", (void**)&window) == B_OK) if (message->FindPointer("window", (void**)&window) == B_OK)
openMessage.AddPointer("window", window); openMessage.AddPointer("window", window);
bool referenceImage;
if (message->FindBool("reference image", &referenceImage) == B_OK)
openMessage.AddBool("reference image", referenceImage);
fOpenPanel->SetMessage(&openMessage); fOpenPanel->SetMessage(&openMessage);
fOpenPanel->Show(); fOpenPanel->Show();
break; break;
@@ -216,6 +224,9 @@ IconEditorApp::RefsReceived(BMessage* message)
bool append; bool append;
if (message->FindBool("append", &append) != B_OK) if (message->FindBool("append", &append) != B_OK)
append = false; append = false;
bool referenceImage;
if (message->FindBool("reference image", &referenceImage) != B_OK)
referenceImage = false;
MainWindow* window; MainWindow* window;
if (message->FindPointer("window", (void**)&window) != B_OK) if (message->FindPointer("window", (void**)&window) != B_OK)
window = NULL; window = NULL;
@@ -223,11 +234,15 @@ IconEditorApp::RefsReceived(BMessage* message)
if (append && window == NULL) if (append && window == NULL)
return; return;
entry_ref ref; entry_ref ref;
if (append) { if (append || referenceImage) {
if (!window->Lock()) if (!window->Lock())
return; return;
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
if (append)
window->Open(ref, true); window->Open(ref, true);
if (referenceImage)
window->AddReferenceImage(ref);
}
window->Unlock(); window->Unlock();
} else { } else {
for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { 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 # icon/shape
PathContainer.cpp PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp Shape.cpp
ShapeContainer.cpp ShapeContainer.cpp
VectorPath.cpp VectorPath.cpp
+64 -9
View File
@@ -1,6 +1,10 @@
/* /*
* Copyright 2006-2011, Stephan Aßmus <[email protected]>. * Copyright 2006-2011, Stephan Aßmus <[email protected]>.
* Copyright 2023, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/ */
#include "MainWindow.h" #include "MainWindow.h"
@@ -9,6 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include <Alert.h> #include <Alert.h>
#include <Bitmap.h>
#include <Catalog.h> #include <Catalog.h>
#include <Clipboard.h> #include <Clipboard.h>
#include <GridLayout.h> #include <GridLayout.h>
@@ -25,8 +30,10 @@
#include <MenuField.h> #include <MenuField.h>
#include <MenuItem.h> #include <MenuItem.h>
#include <Message.h> #include <Message.h>
#include <MimeType.h>
#include <Screen.h> #include <Screen.h>
#include <ScrollView.h> #include <ScrollView.h>
#include <TranslationUtils.h>
#include "support_ui.h" #include "support_ui.h"
@@ -73,6 +80,8 @@
#include "Icon.h" #include "Icon.h"
#include "MultipleManipulatorState.h" #include "MultipleManipulatorState.h"
#include "PathManipulator.h" #include "PathManipulator.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h" #include "Shape.h"
#include "ShapeContainer.h" #include "ShapeContainer.h"
#include "ShapeListView.h" #include "ShapeListView.h"
@@ -207,6 +216,24 @@ MainWindow::MessageReceived(BMessage* message)
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
case B_SIMPLE_DATA: 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, // If our icon is empty, open the file in this window,
// otherwise forward to the application which will open // otherwise forward to the application which will open
// it in another window, unless we append. // it in another window, unless we append.
@@ -214,8 +241,6 @@ MainWindow::MessageReceived(BMessage* message)
if (fDocument->Icon()->Styles()->CountStyles() == 0 if (fDocument->Icon()->Styles()->CountStyles() == 0
&& fDocument->Icon()->Paths()->CountPaths() == 0 && fDocument->Icon()->Paths()->CountPaths() == 0
&& fDocument->Icon()->Shapes()->CountShapes() == 0) { && fDocument->Icon()->Shapes()->CountShapes() == 0) {
entry_ref ref;
if (message->FindRef("refs", &ref) == B_OK)
Open(ref); Open(ref);
break; break;
} }
@@ -226,6 +251,7 @@ MainWindow::MessageReceived(BMessage* message)
} }
be_app->PostMessage(message); be_app->PostMessage(message);
break; break;
}
case B_PASTE: case B_PASTE:
case B_MIME_DATA: case B_MIME_DATA:
@@ -272,15 +298,23 @@ MainWindow::MessageReceived(BMessage* message)
} }
case MSG_OPEN: case MSG_OPEN:
{
// If our icon is empty, we want the icon to open in this // If our icon is empty, we want the icon to open in this
// window. // window.
if (fDocument->Icon()->Styles()->CountStyles() == 0 bool emptyDocument = fDocument->Icon()->Styles()->CountStyles() == 0
&& fDocument->Icon()->Paths()->CountPaths() == 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); message->AddPointer("window", this);
}
be_app->PostMessage(message); be_app->PostMessage(message);
break; break;
}
case MSG_SAVE: case MSG_SAVE:
case MSG_EXPORT: case MSG_EXPORT:
@@ -414,11 +448,9 @@ MainWindow::MessageReceived(BMessage* message)
style = fDocument->Icon()->Styles()->StyleAt(0); style = fDocument->Icon()->Styles()->StyleAt(0);
} }
Shape* shape = new (nothrow) Shape(style); PathSourceShape* shape = new (nothrow) PathSourceShape(style);
Shape* shapes[1];
shapes[0] = shape;
AddShapesCommand* shapeCommand = new (nothrow) AddShapesCommand( AddShapesCommand* shapeCommand = new (nothrow) AddShapesCommand(
fDocument->Icon()->Shapes(), shapes, 1, fDocument->Icon()->Shapes(), (Shape**) &shape, 1,
fDocument->Icon()->Shapes()->CountShapes(), fDocument->Icon()->Shapes()->CountShapes(),
fDocument->Selection()); 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 void
MainWindow::SetIcon(Icon* icon) MainWindow::SetIcon(Icon* icon)
{ {
+5
View File
@@ -1,6 +1,10 @@
/* /*
* Copyright 2006-2010, Stephan Aßmus <[email protected]>. * Copyright 2006-2010, Stephan Aßmus <[email protected]>.
* Copyright 2023, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Zardshard
*/ */
#ifndef MAIN_WINDOW_H #ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H #define MAIN_WINDOW_H
@@ -73,6 +77,7 @@ public:
bool append = false); bool append = false);
void Open(const BMessenger& externalObserver, void Open(const BMessenger& externalObserver,
const uint8* data, size_t size); const uint8* data, size_t size);
void AddReferenceImage(const entry_ref& ref);
void StoreSettings(BMessage* archive); void StoreSettings(BMessage* archive);
void RestoreSettings(const BMessage* archive); void RestoreSettings(const BMessage* archive);
@@ -63,7 +63,7 @@ IconObject::SelectedChanged()
// Unarchive // Unarchive
status_t status_t
IconObject::Unarchive(const BMessage* archive) IconObject::Unarchive(BMessage* archive)
{ {
if (!archive) if (!archive)
return B_BAD_VALUE; return B_BAD_VALUE;
+1 -1
View File
@@ -31,7 +31,7 @@ class IconObject : public Observable,
virtual void SelectedChanged(); virtual void SelectedChanged();
// IconObject // IconObject
virtual status_t Unarchive(const BMessage* archive); virtual status_t Unarchive(BMessage* archive);
virtual status_t Archive(BMessage* into, virtual status_t Archive(BMessage* into,
bool deep = true) const; bool deep = true) const;
@@ -30,6 +30,9 @@ name_for_id(int32 id)
name = B_TRANSLATE("Name"); name = B_TRANSLATE("Name");
break; break;
case PROPERTY_ALPHA:
name = B_TRANSLATE("Alpha");
break;
case PROPERTY_OPACITY: case PROPERTY_OPACITY:
name = B_TRANSLATE("Opacity"); name = B_TRANSLATE("Opacity");
break; break;
@@ -14,7 +14,8 @@
enum { enum {
PROPERTY_NAME = 'name', PROPERTY_NAME = 'name',
PROPERTY_OPACITY = 'alpa', PROPERTY_ALPHA = 'alpa',
PROPERTY_OPACITY = 'opac',
PROPERTY_COLOR = 'colr', PROPERTY_COLOR = 'colr',
PROPERTY_WIDTH = 'wdth', PROPERTY_WIDTH = 'wdth',
+1 -1
View File
@@ -57,7 +57,7 @@ void
IconView::Draw(BRect updateRect) IconView::Draw(BRect updateRect)
{ {
if (fDirtyIconArea.IsValid()) { if (fDirtyIconArea.IsValid()) {
fRenderer->Render(fDirtyIconArea); fRenderer->Render(fDirtyIconArea, false);
fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); fDirtyIconArea.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
} }
+5 -4
View File
@@ -26,6 +26,7 @@
#include "CommandStack.h" #include "CommandStack.h"
#include "MovePathsCommand.h" #include "MovePathsCommand.h"
#include "Observer.h" #include "Observer.h"
#include "PathSourceShape.h"
#include "RemovePathsCommand.h" #include "RemovePathsCommand.h"
#include "ReversePathCommand.h" #include "ReversePathCommand.h"
#include "RotatePathIndicesCommand.h" #include "RotatePathIndicesCommand.h"
@@ -242,7 +243,7 @@ public:
// ShapePathListener // ShapePathListener
void SetShape(Shape* shape) void SetShape(PathSourceShape* shape)
{ {
if (fShape == shape) if (fShape == shape)
return; return;
@@ -264,7 +265,7 @@ public:
private: private:
PathListView* fListView; PathListView* fListView;
Shape* fShape; PathSourceShape* fShape;
}; };
@@ -868,8 +869,8 @@ PathListView::SetCurrentShape(Shape* shape)
if (fCurrentShape == shape) if (fCurrentShape == shape)
return; return;
fCurrentShape = shape; fCurrentShape = dynamic_cast<PathSourceShape*>(shape);
fShapePathListener->SetShape(shape); fShapePathListener->SetShape(fCurrentShape);
_UpdateMarks(); _UpdateMarks();
} }
+3 -2
View File
@@ -18,6 +18,7 @@ class BMenuItem;
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class VectorPath; class VectorPath;
class PathSourceShape;
class Shape; class Shape;
class ShapeContainer; class ShapeContainer;
_END_ICON_NAMESPACE _END_ICON_NAMESPACE
@@ -74,7 +75,7 @@ class PathListView : public SimpleListView,
void SetMenu(BMenu* menu); void SetMenu(BMenu* menu);
void SetCurrentShape(Shape* shape); void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const PathSourceShape* CurrentShape() const
{ return fCurrentShape; } { return fCurrentShape; }
private: private:
@@ -106,7 +107,7 @@ class PathListView : public SimpleListView,
ShapeContainer* fShapeContainer; ShapeContainer* fShapeContainer;
CommandStack* fCommandStack; CommandStack* fCommandStack;
Shape* fCurrentShape; PathSourceShape* fCurrentShape;
// those path items will be marked that // those path items will be marked that
// are referenced by this shape // are referenced by this shape
+91 -9
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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "ShapeListView.h" #include "ShapeListView.h"
@@ -27,9 +28,12 @@
#include "CommandStack.h" #include "CommandStack.h"
#include "CompoundCommand.h" #include "CompoundCommand.h"
#include "FreezeTransformationCommand.h" #include "FreezeTransformationCommand.h"
#include "MainWindow.h"
#include "MoveShapesCommand.h" #include "MoveShapesCommand.h"
#include "Observer.h" #include "Observer.h"
#include "ReferenceImage.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "RemoveShapesCommand.h" #include "RemoveShapesCommand.h"
#include "ResetTransformationCommand.h" #include "ResetTransformationCommand.h"
#include "Selection.h" #include "Selection.h"
@@ -214,8 +218,19 @@ ShapeListView::MessageReceived(BMessage* message)
if (count < 0) if (count < 0)
break; 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 FreezeTransformationCommand* command
= new FreezeTransformationCommand((Shape**)shapes.Items(), = new FreezeTransformationCommand(
(PathSourceShape**)pathSourceShapes.Items(),
count); count);
fCommandStack->Perform(command); fCommandStack->Perform(command);
@@ -239,16 +254,21 @@ ShapeListView::MakeDragMessage(BMessage* message) const
ShapeListItem* item = dynamic_cast<ShapeListItem*>( ShapeListItem* item = dynamic_cast<ShapeListItem*>(
ItemAt(CurrentSelection(i))); ItemAt(CurrentSelection(i)));
if (item != NULL && item->shape != NULL) { if (item != NULL && item->shape != NULL) {
message->AddPointer("shape", (void*)item->shape); PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(item->shape);
if (pathSourceShape != NULL) {
message->AddInt32("type", PathSourceShape::archive_code);
PathSourceShape* shape = pathSourceShape;
message->AddPointer("shape", (void*)shape);
// Add archives of everything this Shape uses // Add archives of everything this Shape uses
BMessage archive; BMessage archive;
BMessage styleArchive; BMessage styleArchive;
item->shape->Style()->Archive(&styleArchive, true); shape->Style()->Archive(&styleArchive, true);
archive.AddMessage("style", &styleArchive); archive.AddMessage("style", &styleArchive);
PathContainer* paths = item->shape->Paths(); PathContainer* paths = shape->Paths();
for (int32 j = 0; j < paths->CountPaths(); j++) { for (int32 j = 0; j < paths->CountPaths(); j++) {
BMessage pathArchive; BMessage pathArchive;
paths->PathAt(j)->Archive(&pathArchive, true); paths->PathAt(j)->Archive(&pathArchive, true);
@@ -256,10 +276,29 @@ ShapeListView::MakeDragMessage(BMessage* message) const
} }
BMessage shapeArchive; BMessage shapeArchive;
item->shape->Archive(&shapeArchive, true); shape->Archive(&shapeArchive, true);
archive.AddMessage("shape", &shapeArchive); archive.AddMessage("shape", &shapeArchive);
message->AddMessage("shape archive", &archive); message->AddMessage("shape archive", &archive);
continue;
}
ReferenceImage* referenceImage = dynamic_cast<ReferenceImage*>(item->shape);
if (referenceImage != NULL) {
message->AddInt32("type", ReferenceImage::archive_code);
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 } else
break; break;
} }
@@ -300,6 +339,11 @@ ShapeListView::HandleDropMessage(const BMessage* message, int32 dropIndex)
BList paths; BList paths;
BList shapes; BList shapes;
while (true) { while (true) {
int32 type;
if (message->FindInt32("type", index, &type) != B_OK)
break;
if (type == PathSourceShape::archive_code) {
BMessage archive; BMessage archive;
if (message->FindMessage("shape archive", index, &archive) != B_OK) if (message->FindMessage("shape archive", index, &archive) != B_OK)
break; break;
@@ -337,7 +381,7 @@ ShapeListView::HandleDropMessage(const BMessage* message, int32 dropIndex)
} }
// Create the shape using the given style // Create the shape using the given style
Shape* shape = new(std::nothrow) Shape(styleToAssign); PathSourceShape* shape = new(std::nothrow) PathSourceShape(styleToAssign);
if (shape == NULL) if (shape == NULL)
break; break;
@@ -382,6 +426,22 @@ ShapeListView::HandleDropMessage(const BMessage* message, int32 dropIndex)
pathIndex++; 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++; index++;
} }
@@ -462,7 +522,7 @@ ShapeListView::CopyItems(BList& items, int32 toIndex)
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
ShapeListItem* item ShapeListItem* item
= dynamic_cast<ShapeListItem*>((BListItem*)items.ItemAtFast(i)); = 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, AddShapesCommand* command = new(nothrow) AddShapesCommand(fShapeContainer,
@@ -612,6 +672,10 @@ ShapeListView::SetMenu(BMenu* menu)
fAddWidthPathAndStyleMI = new BMenuItem( fAddWidthPathAndStyleMI = new BMenuItem(
B_TRANSLATE("Add with path & style"), message); 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"), fDuplicateMI = new BMenuItem(B_TRANSLATE("Duplicate"),
new BMessage(MSG_DUPLICATE)); new BMessage(MSG_DUPLICATE));
fResetTransformationMI = new BMenuItem(B_TRANSLATE("Reset transformation"), fResetTransformationMI = new BMenuItem(B_TRANSLATE("Reset transformation"),
@@ -630,10 +694,13 @@ ShapeListView::SetMenu(BMenu* menu)
fMenu->AddSeparatorItem(); fMenu->AddSeparatorItem();
fMenu->AddItem(fAddReferenceImageMI);
fMenu->AddSeparatorItem();
fMenu->AddItem(fDuplicateMI); fMenu->AddItem(fDuplicateMI);
fMenu->AddItem(fResetTransformationMI); fMenu->AddItem(fResetTransformationMI);
fMenu->AddItem(fFreezeTransformationMI); fMenu->AddItem(fFreezeTransformationMI);
fMenu->AddSeparatorItem(); fMenu->AddSeparatorItem();
fMenu->AddItem(fRemoveMI); fMenu->AddItem(fRemoveMI);
@@ -753,6 +820,21 @@ ShapeListView::_UpdateMenu()
fResetTransformationMI->SetEnabled(gotSelection); fResetTransformationMI->SetEnabled(gotSelection);
fFreezeTransformationMI->SetEnabled(gotSelection); fFreezeTransformationMI->SetEnabled(gotSelection);
fRemoveMI->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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#ifndef SHAPE_LIST_VIEW_H #ifndef SHAPE_LIST_VIEW_H
#define SHAPE_LIST_VIEW_H #define SHAPE_LIST_VIEW_H
@@ -30,6 +31,7 @@ _USING_ICON_NAMESPACE
enum { enum {
MSG_ADD_SHAPE = 'adsh', MSG_ADD_SHAPE = 'adsh',
MSG_ADD_REFERENCE_IMAGE = 'aimg',
}; };
class ShapeListView : public SimpleListView, class ShapeListView : public SimpleListView,
@@ -95,6 +97,7 @@ class ShapeListView : public SimpleListView,
BMenuItem* fAddWidthPathMI; BMenuItem* fAddWidthPathMI;
BMenuItem* fAddWidthStyleMI; BMenuItem* fAddWidthStyleMI;
BMenuItem* fAddWidthPathAndStyleMI; BMenuItem* fAddWidthPathAndStyleMI;
BMenuItem* fAddReferenceImageMI;
BMenuItem* fDuplicateMI; BMenuItem* fDuplicateMI;
BMenuItem* fResetTransformationMI; BMenuItem* fResetTransformationMI;
BMenuItem* fFreezeTransformationMI; BMenuItem* fFreezeTransformationMI;
+9 -6
View File
@@ -25,6 +25,7 @@
#include "CommandStack.h" #include "CommandStack.h"
#include "GradientTransformable.h" #include "GradientTransformable.h"
#include "MoveStylesCommand.h" #include "MoveStylesCommand.h"
#include "PathSourceShape.h"
#include "RemoveStylesCommand.h" #include "RemoveStylesCommand.h"
#include "Style.h" #include "Style.h"
#include "Observer.h" #include "Observer.h"
@@ -236,7 +237,7 @@ public:
} }
// ShapeStyleListener // ShapeStyleListener
void SetShape(Shape* shape) void SetShape(PathSourceShape* shape)
{ {
if (fShape == shape) if (fShape == shape)
return; return;
@@ -250,14 +251,14 @@ public:
fShape->AddListener(this); fShape->AddListener(this);
} }
Shape* CurrentShape() const PathSourceShape* CurrentShape() const
{ {
return fShape; return fShape;
} }
private: private:
StyleListView* fListView; StyleListView* fListView;
Shape* fShape; PathSourceShape* fShape;
}; };
@@ -769,11 +770,13 @@ StyleListView::SetCurrentColor(CurrentColor* color)
void void
StyleListView::SetCurrentShape(Shape* shape) StyleListView::SetCurrentShape(Shape* shape)
{ {
if (fCurrentShape == shape) PathSourceShape* pathSourceShape = dynamic_cast<PathSourceShape*>(shape);
if (fCurrentShape == pathSourceShape)
return; return;
fCurrentShape = shape; fCurrentShape = pathSourceShape;
fShapeListener->SetShape(shape); fShapeListener->SetShape(pathSourceShape);
_UpdateMarks(); _UpdateMarks();
} }
+3 -2
View File
@@ -19,6 +19,7 @@ class ShapeStyleListener;
class StyleListItem; class StyleListItem;
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class PathSourceShape;
class Shape; class Shape;
class ShapeContainer; class ShapeContainer;
class ShapeListener; class ShapeListener;
@@ -72,7 +73,7 @@ public:
void SetCurrentColor(CurrentColor* color); void SetCurrentColor(CurrentColor* color);
void SetCurrentShape(Shape* shape); void SetCurrentShape(Shape* shape);
Shape* CurrentShape() const PathSourceShape* CurrentShape() const
{ return fCurrentShape; } { return fCurrentShape; }
private: private:
@@ -93,7 +94,7 @@ private:
CommandStack* fCommandStack; CommandStack* fCommandStack;
CurrentColor* fCurrentColor; CurrentColor* fCurrentColor;
Shape* fCurrentShape; PathSourceShape* fCurrentShape;
// the style item will be marked that // the style item will be marked that
// is referenced by this shape // is referenced by this shape
@@ -24,6 +24,7 @@
#include "AddTransformersCommand.h" #include "AddTransformersCommand.h"
#include "CommandStack.h" #include "CommandStack.h"
#include "MoveTransformersCommand.h" #include "MoveTransformersCommand.h"
#include "ReferenceImage.h"
#include "RemoveTransformersCommand.h" #include "RemoveTransformersCommand.h"
#include "Transformer.h" #include "Transformer.h"
#include "TransformerFactory.h" #include "TransformerFactory.h"
@@ -386,20 +387,31 @@ TransformerListView::SetMenu(BMenu* menu)
return; return;
BMenu* addMenu = new BMenu(B_TRANSLATE("Add")); BMenu* addMenu = new BMenu(B_TRANSLATE("Add"));
int32 cookie = 0;
uint32 type; // Keep translated strings that were brought in from another file
BString name; #undef B_TRANSLATION_CONTEXT
while (TransformerFactory::NextType(&cookie, &type, &name)) { #define B_TRANSLATION_CONTEXT "Transformation"
// 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); BMessage* message = new BMessage(MSG_ADD_TRANSFORMER);
message->AddInt32("type", type); message->AddInt32("type", CONTOUR_TRANSFORMER);
addMenu->AddItem(new BMenuItem(name.String(), message)); 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); addMenu->SetTargetForItems(this);
fMenu->AddItem(addMenu); fMenu->AddItem(addMenu);
@@ -480,4 +492,8 @@ void
TransformerListView::_UpdateMenu() TransformerListView::_UpdateMenu()
{ {
fMenu->SetEnabled(fShape != NULL); fMenu->SetEnabled(fShape != NULL);
bool isReferenceImage = dynamic_cast<ReferenceImage*>(fShape) != NULL;
fContourMI->SetEnabled(!isReferenceImage);
fStrokeMI->SetEnabled(!isReferenceImage);
} }
@@ -14,6 +14,7 @@
class BMenu; class BMenu;
class BMenuItem;
class CommandStack; class CommandStack;
class TransformerItem; class TransformerItem;
class Selection; class Selection;
@@ -79,6 +80,8 @@ class TransformerListView : public SimpleListView,
CommandStack* fCommandStack; CommandStack* fCommandStack;
BMenu* fMenu; BMenu* fMenu;
BMenuItem* fContourMI;
BMenuItem* fStrokeMI;
}; };
#endif // TRANSFORMER_LIST_VIEW_H #endif // TRANSFORMER_LIST_VIEW_H
@@ -15,6 +15,8 @@
#include "Icon.h" #include "Icon.h"
#include "IconRenderer.h" #include "IconRenderer.h"
#include "ReferenceImage.h"
// constructor // constructor
BitmapExporter::BitmapExporter(uint32 size) BitmapExporter::BitmapExporter(uint32 size)
@@ -53,7 +55,7 @@ BitmapExporter::Export(const Icon* icon, BPositionIO* stream)
IconRenderer renderer(&bitmap); IconRenderer renderer(&bitmap);
renderer.SetIcon(icon); renderer.SetIcon(icon);
renderer.SetScale(fSize / 64.0); renderer.SetScale(fSize / 64.0);
renderer.Render(); renderer.Render(false);
// renderer.Demultiply(&bitmap); // renderer.Demultiply(&bitmap);
// save bitmap to translator // 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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "FlatIconExporter.h" #include "FlatIconExporter.h"
@@ -24,7 +25,9 @@
#include "LittleEndianBuffer.h" #include "LittleEndianBuffer.h"
#include "PathCommandQueue.h" #include "PathCommandQueue.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "PerspectiveTransformer.h" #include "PerspectiveTransformer.h"
#include "ReferenceImage.h"
#include "Shape.h" #include "Shape.h"
#include "StrokeTransformer.h" #include "StrokeTransformer.h"
#include "Style.h" #include "Style.h"
@@ -477,7 +480,7 @@ _WriteTransformer(LittleEndianBuffer& buffer, Transformer* t)
// _WritePathSourceShape // _WritePathSourceShape
static bool static bool
_WritePathSourceShape(LittleEndianBuffer& buffer, Shape* shape, _WritePathSourceShape(LittleEndianBuffer& buffer, PathSourceShape* shape,
StyleContainer* styles, PathContainer* paths) StyleContainer* styles, PathContainer* paths)
{ {
// find out which style this shape uses // find out which style this shape uses
@@ -575,17 +578,32 @@ FlatIconExporter::_WriteShapes(LittleEndianBuffer& buffer,
PathContainer* paths, PathContainer* paths,
ShapeContainer* shapes) ShapeContainer* shapes)
{ {
if (shapes->CountShapes() > 255) uint32 shapeCount = shapes->CountShapes();
return B_RESULT_NOT_REPRESENTABLE;
uint8 shapeCount = min_c(255, shapes->CountShapes());
if (!buffer.Write(shapeCount))
return B_NO_MEMORY;
// Count the number of exportable shapes
uint32 pathShapeCount = 0;
for (uint32 i = 0; i < shapeCount; i++) { for (uint32 i = 0; i < shapeCount; i++) {
Shape* shape = shapes->ShapeAtFast(i); Shape* shape = shapes->ShapeAtFast(i);
if (!_WritePathSourceShape(buffer, shape, styles, paths)) 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_ERROR;
} }
}
return B_OK; 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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "MessageExporter.h" #include "MessageExporter.h"
@@ -16,6 +17,8 @@
#include "Defines.h" #include "Defines.h"
#include "Icon.h" #include "Icon.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h" #include "Shape.h"
#include "Style.h" #include "Style.h"
#include "StyleContainer.h" #include "StyleContainer.h"
@@ -150,6 +153,12 @@ MessageExporter::_Export(const Shape* shape,
const StyleContainer* globalStyles, const StyleContainer* globalStyles,
BMessage* into) const BMessage* into) const
{ {
status_t ret = B_OK;
const PathSourceShape* pathSourceShape = dynamic_cast<const PathSourceShape*>(shape);
if (pathSourceShape != NULL) {
ret = into->AddInt32("type", PathSourceShape::archive_code);
// NOTE: when the same path is used in two different // NOTE: when the same path is used in two different
// documents, and these are to be merged, each path // documents, and these are to be merged, each path
// having a "globally unique" id would make it possible // having a "globally unique" id would make it possible
@@ -158,19 +167,27 @@ MessageExporter::_Export(const Shape* shape,
// globalPaths container. // globalPaths container.
// index of used style // index of used style
Style* style = shape->Style(); if (ret == B_OK) {
status_t ret = into->AddInt32("style ref", globalStyles->IndexOf(style)); Style* style = pathSourceShape->Style();
ret = into->AddInt32("style ref", globalStyles->IndexOf(style));
}
// indices of used paths // indices of used paths
if (ret == B_OK) { if (ret == B_OK) {
int32 count = shape->Paths()->CountPaths(); int32 count = pathSourceShape->Paths()->CountPaths();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
VectorPath* path = shape->Paths()->PathAtFast(i); VectorPath* path = pathSourceShape->Paths()->PathAtFast(i);
ret = into->AddInt32("path ref", globalPaths->IndexOf(path)); ret = into->AddInt32("path ref", globalPaths->IndexOf(path));
if (ret < B_OK) if (ret < B_OK)
break; break;
} }
} }
}
const ReferenceImage* referenceImage = dynamic_cast<const ReferenceImage*>(shape);
if (referenceImage != NULL) {
ret = into->AddInt32("type", ReferenceImage::archive_code);
}
// Shape properties // Shape properties
if (ret == B_OK) if (ret == B_OK)
@@ -29,7 +29,7 @@
#include "Defines.h" #include "Defines.h"
#include "Icon.h" #include "Icon.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "Shape.h" #include "PathSourceShape.h"
#include "Style.h" #include "Style.h"
#include "StyleContainer.h" #include "StyleContainer.h"
#include "VectorPath.h" #include "VectorPath.h"
@@ -45,7 +45,7 @@ using std::nothrow;
class ShapeIterator : public BShapeIterator { class ShapeIterator : public BShapeIterator {
public: public:
ShapeIterator(Icon *icon, Shape *to, BPoint offset, const char *name); ShapeIterator(Icon *icon, PathSourceShape *to, BPoint offset, const char *name);
~ShapeIterator() {}; ~ShapeIterator() {};
virtual status_t IterateMoveTo(BPoint *point); virtual status_t IterateMoveTo(BPoint *point);
@@ -58,7 +58,7 @@ class ShapeIterator : public BShapeIterator {
void NextPath(); void NextPath();
Icon *fIcon; Icon *fIcon;
Shape *fShape; PathSourceShape *fShape;
VectorPath *fPath; VectorPath *fPath;
BPoint fOffset; BPoint fOffset;
const char *fName; const char *fName;
@@ -66,7 +66,7 @@ class ShapeIterator : public BShapeIterator {
bool fHasLastPoint; bool fHasLastPoint;
}; };
ShapeIterator::ShapeIterator(Icon *icon, Shape *to, BPoint offset, ShapeIterator::ShapeIterator(Icon *icon, PathSourceShape *to, BPoint offset,
const char *name) const char *name)
{ {
CALLED(); CALLED();
@@ -328,7 +328,7 @@ StyledTextImporter::_Import(Icon* icon, const char *text, text_run_array *runs)
if (glyph.Bounds().IsValid()) { if (glyph.Bounds().IsValid()) {
//offset.x += glyph.Bounds().Width(); //offset.x += glyph.Bounds().Width();
offset.x += charWidth; offset.x += charWidth;
Shape* shape = new (nothrow) Shape(NULL); PathSourceShape* shape = new (nothrow) PathSourceShape(NULL);
if (shape == NULL) if (shape == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
shape->SetName(glyphName.String()); shape->SetName(glyphName.String());
@@ -19,7 +19,7 @@
#include "GradientTransformable.h" #include "GradientTransformable.h"
#include "Icon.h" #include "Icon.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "Shape.h" #include "PathSourceShape.h"
#include "ShapeContainer.h" #include "ShapeContainer.h"
#include "StrokeTransformer.h" #include "StrokeTransformer.h"
#include "Style.h" #include "Style.h"
@@ -112,9 +112,12 @@ printf("scale: %f\n", scale);
// clean up styles and paths (remove duplicates) // clean up styles and paths (remove duplicates)
int32 count = icon->Shapes()->CountShapes(); int32 count = icon->Shapes()->CountShapes();
for (int32 i = 1; i < count; i++) { 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(); Style* style = shape->Style();
if (!style) if (style == NULL)
continue; continue;
int32 styleIndex = icon->Styles()->IndexOf(style); int32 styleIndex = icon->Styles()->IndexOf(style);
for (int32 j = 0; j < styleIndex; j++) { for (int32 j = 0; j < styleIndex; j++) {
@@ -134,7 +137,7 @@ printf("scale: %f\n", scale);
// AddVertexSource // AddVertexSource
status_t status_t
AddPathsFromVertexSource(Icon* icon, Shape* shape, NSVGshape* svgShape) AddPathsFromVertexSource(Icon* icon, PathSourceShape* shape, NSVGshape* svgShape)
{ {
//printf("AddPathsFromVertexSource(pathID = %ld)\n", index); //printf("AddPathsFromVertexSource(pathID = %ld)\n", index);
@@ -194,7 +197,7 @@ status_t
DocumentBuilder::_AddShape(NSVGshape* svgShape, bool outline, DocumentBuilder::_AddShape(NSVGshape* svgShape, bool outline,
const Transformable& transform, Icon* icon) const Transformable& transform, Icon* icon)
{ {
Shape* shape = new (nothrow) Shape(NULL); PathSourceShape* shape = new (nothrow) PathSourceShape(NULL);
if (!shape || !icon->Shapes()->AddShape(shape)) { if (!shape || !icon->Shapes()->AddShape(shape)) {
delete shape; delete shape;
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -245,7 +248,7 @@ DocumentBuilder::_AddShape(NSVGshape* svgShape, bool outline,
} }
} else { } else {
paint = &svgShape->fill; 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) if (svgShape->fillRule == NSVG_FILLRULE_EVENODD)
shape->SetFillingRule(FILL_MODE_EVEN_ODD); shape->SetFillingRule(FILL_MODE_EVEN_ODD);
else 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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include <stdio.h> #include <stdio.h>
@@ -19,6 +20,7 @@
#include "Icon.h" #include "Icon.h"
#include "GradientTransformable.h" #include "GradientTransformable.h"
#include "PathSourceShape.h"
#include "Shape.h" #include "Shape.h"
#include "StrokeTransformer.h" #include "StrokeTransformer.h"
#include "Style.h" #include "Style.h"
@@ -200,14 +202,19 @@ convert_cap_mode_svg(agg::line_cap_e mode)
status_t status_t
SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream) SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
{ {
if (shape->MaxVisibilityScale() < 1.0 if (!shape->Visible(1.0)) {
|| shape->MinVisibilityScale() > 1.0) {
// don't export shapes which are not visible at the // don't export shapes which are not visible at the
// default scale // default scale
return B_OK; 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]; char color[64];
status_t ret = _GetFill(style, color, stream); 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 // hack to see if this is an outline shape
StrokeTransformer* stroke StrokeTransformer* stroke
= dynamic_cast<StrokeTransformer*>(shape->TransformerAt(0)); = dynamic_cast<StrokeTransformer*>(pathSourceShape->TransformerAt(0));
if (stroke) { if (stroke) {
helper << "style=\"fill:none; stroke:" << color; helper << "style=\"fill:none; stroke:" << color;
if (!style->Gradient() && style->Color().alpha < 255) { 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); append_float(helper, style->Color().alpha / 255.0);
} }
// if (shape->FillingRule() == FILL_MODE_EVEN_ODD && // if (pathSourceShape->FillingRule() == FILL_MODE_EVEN_ODD &&
// shape->Paths()->CountPaths() > 1) // pathSourceShape->Paths()->CountPaths() > 1)
// helper << "; fill-rule:evenodd"; // helper << "; fill-rule:evenodd";
helper << "\"\n"; helper << "\"\n";
@@ -272,9 +279,9 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
if (ret < B_OK) if (ret < B_OK)
return ret; return ret;
int32 count = shape->Paths()->CountPaths(); int32 count = pathSourceShape->Paths()->CountPaths();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
VectorPath* path = shape->Paths()->PathAtFast(i); VectorPath* path = pathSourceShape->Paths()->PathAtFast(i);
if (i > 0) { if (i > 0) {
helper << "\n "; helper << "\n ";
@@ -340,9 +347,9 @@ SVGExporter::_ExportShape(const Shape* shape, BPositionIO* stream)
} }
helper << "\"\n"; helper << "\"\n";
if (!shape->IsIdentity()) { if (!pathSourceShape->IsIdentity()) {
helper << " transform=\""; helper << " transform=\"";
_AppendMatrix(shape, helper); _AppendMatrix(pathSourceShape, helper);
helper << "\n"; helper << "\n";
} }
@@ -16,7 +16,7 @@
#include <Locale.h> #include <Locale.h>
#include "GradientTransformable.h" #include "GradientTransformable.h"
#include "Shape.h" #include "PathSourceShape.h"
#include "Style.h" #include "Style.h"
#include "VectorPath.h" #include "VectorPath.h"
@@ -29,10 +29,10 @@ using std::nothrow;
// constructor // constructor
FreezeTransformationCommand::FreezeTransformationCommand( FreezeTransformationCommand::FreezeTransformationCommand(
Shape** const shapes, PathSourceShape** const shapes,
int32 count) int32 count)
: Command(), : 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[ fOriginalTransformations(count > 0 ? new (nothrow) double[
count * Transformable::matrix_size] count * Transformable::matrix_size]
: NULL), : NULL),
@@ -41,7 +41,7 @@ FreezeTransformationCommand::FreezeTransformationCommand(
if (!fShapes || !fOriginalTransformations) if (!fShapes || !fOriginalTransformations)
return; return;
memcpy(fShapes, shapes, sizeof(Shape*) * fCount); memcpy(fShapes, shapes, sizeof(PathSourceShape*) * fCount);
bool initOk = false; bool initOk = false;
@@ -128,7 +128,7 @@ FreezeTransformationCommand::GetName(BString& name)
// _ApplyTransformation // _ApplyTransformation
void void
FreezeTransformationCommand::_ApplyTransformation(Shape* shape, FreezeTransformationCommand::_ApplyTransformation(PathSourceShape* shape,
const Transformable& transform) const Transformable& transform)
{ {
// apply inverse of old shape transformation to every assigned path // apply inverse of old shape transformation to every assigned path
@@ -14,7 +14,7 @@
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class Shape; class PathSourceShape;
class Transformable; class Transformable;
_END_ICON_NAMESPACE _END_ICON_NAMESPACE
@@ -24,7 +24,7 @@ _USING_ICON_NAMESPACE
class FreezeTransformationCommand : public Command { class FreezeTransformationCommand : public Command {
public: public:
FreezeTransformationCommand( FreezeTransformationCommand(
Shape** const shapes, PathSourceShape** const shapes,
int32 count); int32 count);
virtual ~FreezeTransformationCommand(); virtual ~FreezeTransformationCommand();
@@ -36,10 +36,10 @@ class FreezeTransformationCommand : public Command {
virtual void GetName(BString& name); virtual void GetName(BString& name);
private: private:
void _ApplyTransformation(Shape* shape, void _ApplyTransformation(PathSourceShape* shape,
const Transformable& transform); const Transformable& transform);
Shape** fShapes; PathSourceShape** fShapes;
double* fOriginalTransformations; double* fOriginalTransformations;
int32 fCount; int32 fCount;
}; };
@@ -15,6 +15,7 @@
#include <Locale.h> #include <Locale.h>
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "Shape.h" #include "Shape.h"
#include "VectorPath.h" #include "VectorPath.h"
@@ -44,7 +45,8 @@ RemovePathsCommand::RemovePathsCommand(PathContainer* container,
if (paths[i]) { if (paths[i]) {
int32 listenerCount = paths[i]->CountListeners(); int32 listenerCount = paths[i]->CountListeners();
for (int32 j = 0; j < listenerCount; j++) { 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) if (shape)
fInfos[i].shapes.AddItem((void*)shape); fInfos[i].shapes.AddItem((void*)shape);
} }
@@ -82,7 +84,7 @@ RemovePathsCommand::Perform()
fContainer->RemovePath(fInfos[i].path); fContainer->RemovePath(fInfos[i].path);
int32 shapeCount = fInfos[i].shapes.CountItems(); int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) { 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); shape->Paths()->RemovePath(fInfos[i].path);
} }
} }
@@ -108,7 +110,7 @@ RemovePathsCommand::Undo()
fContainer->RemovePath(fInfos[j].path); fContainer->RemovePath(fInfos[j].path);
int32 shapeCount = fInfos[j].shapes.CountItems(); int32 shapeCount = fInfos[j].shapes.CountItems();
for (int32 k = 0; k < shapeCount; k++) { 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); shape->Paths()->RemovePath(fInfos[j].path);
} }
} }
@@ -116,7 +118,7 @@ RemovePathsCommand::Undo()
} }
int32 shapeCount = fInfos[i].shapes.CountItems(); int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) { 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); shape->Paths()->AddPath(fInfos[i].path);
} }
} }
@@ -12,7 +12,7 @@
#include <Locale.h> #include <Locale.h>
#include "PathContainer.h" #include "PathContainer.h"
#include "Shape.h" #include "PathSourceShape.h"
#include "VectorPath.h" #include "VectorPath.h"
@@ -21,7 +21,7 @@
// constructor // constructor
UnassignPathCommand::UnassignPathCommand(Shape* shape, UnassignPathCommand::UnassignPathCommand(PathSourceShape* shape,
VectorPath* path) VectorPath* path)
: Command(), : Command(),
fShape(shape), fShape(shape),
@@ -14,7 +14,7 @@
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class Shape; class PathSourceShape;
class VectorPath; class VectorPath;
_END_ICON_NAMESPACE _END_ICON_NAMESPACE
@@ -23,7 +23,7 @@ _USING_ICON_NAMESPACE
class UnassignPathCommand : public Command { class UnassignPathCommand : public Command {
public: public:
UnassignPathCommand(Shape* shape, UnassignPathCommand(PathSourceShape* shape,
VectorPath* path); VectorPath* path);
virtual ~UnassignPathCommand(); virtual ~UnassignPathCommand();
@@ -35,7 +35,7 @@ class UnassignPathCommand : public Command {
virtual void GetName(BString& name); virtual void GetName(BString& name);
private: private:
Shape* fShape; PathSourceShape* fShape;
VectorPath* fPath; VectorPath* fPath;
bool fPathRemoved; bool fPathRemoved;
}; };
@@ -11,6 +11,7 @@
#include <Catalog.h> #include <Catalog.h>
#include <Locale.h> #include <Locale.h>
#include "PathSourceShape.h"
#include "Shape.h" #include "Shape.h"
#include "Style.h" #include "Style.h"
@@ -20,7 +21,7 @@
// constructor // constructor
AssignStyleCommand::AssignStyleCommand(Shape* shape, AssignStyleCommand::AssignStyleCommand(PathSourceShape* shape,
Style* style) Style* style)
: Command(), : Command(),
fShape(shape), fShape(shape),
@@ -16,7 +16,7 @@
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class Shape; class PathSourceShape;
class Style; class Style;
_END_ICON_NAMESPACE _END_ICON_NAMESPACE
@@ -25,7 +25,7 @@ _USING_ICON_NAMESPACE
class AssignStyleCommand : public Command { class AssignStyleCommand : public Command {
public: public:
AssignStyleCommand(Shape* shape, AssignStyleCommand(PathSourceShape* shape,
Style* style); Style* style);
virtual ~AssignStyleCommand(); virtual ~AssignStyleCommand();
@@ -37,7 +37,7 @@ class AssignStyleCommand : public Command {
virtual void GetName(BString& name); virtual void GetName(BString& name);
private: private:
Shape* fShape; PathSourceShape* fShape;
Style* fOldStyle; Style* fOldStyle;
Style* fNewStyle; Style* fNewStyle;
}; };
@@ -14,8 +14,8 @@
#include <Catalog.h> #include <Catalog.h>
#include <Locale.h> #include <Locale.h>
#include "PathSourceShape.h"
#include "StyleContainer.h" #include "StyleContainer.h"
#include "Shape.h"
#include "Style.h" #include "Style.h"
@@ -44,8 +44,9 @@ RemoveStylesCommand::RemoveStylesCommand(StyleContainer* container,
if (styles[i]) { if (styles[i]) {
int32 listenerCount = styles[i]->CountObservers(); int32 listenerCount = styles[i]->CountObservers();
for (int32 j = 0; j < listenerCount; j++) { for (int32 j = 0; j < listenerCount; j++) {
Shape* shape = dynamic_cast<Shape*>(styles[i]->ObserverAtFast(j)); PathSourceShape* shape
if (shape) = dynamic_cast<PathSourceShape*>(styles[i]->ObserverAtFast(j));
if (shape != NULL)
fInfos[i].shapes.AddItem((void*)shape); fInfos[i].shapes.AddItem((void*)shape);
} }
} }
@@ -88,7 +89,7 @@ RemoveStylesCommand::Perform()
continue; continue;
int32 shapeCount = fInfos[i].shapes.CountItems(); int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) { 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)); shape->SetStyle(fContainer->StyleAt(0));
} }
} }
@@ -117,7 +118,7 @@ RemoveStylesCommand::Undo()
for (int32 j = i - 1; j >= 0; j--) { for (int32 j = i - 1; j >= 0; j--) {
int32 shapeCount = fInfos[j].shapes.CountItems(); int32 shapeCount = fInfos[j].shapes.CountItems();
for (int32 k = 0; k < shapeCount; k++) { 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)); shape->SetStyle(fContainer->StyleAt(0));
} }
} }
@@ -125,7 +126,7 @@ RemoveStylesCommand::Undo()
} }
int32 shapeCount = fInfos[i].shapes.CountItems(); int32 shapeCount = fInfos[i].shapes.CountItems();
for (int32 j = 0; j < shapeCount; j++) { 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); shape->SetStyle(fInfos[i].style);
} }
} }
+2
View File
@@ -38,6 +38,8 @@ BuildPlatformMergeObjectPIC <libbe_build>icon_kit.o :
# shape # shape
PathContainer.cpp PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp Shape.cpp
ShapeContainer.cpp ShapeContainer.cpp
VectorPath.cpp VectorPath.cpp
+2
View File
@@ -36,6 +36,8 @@ BuildPlatformStaticLibrary libicon_build.a :
# shape # shape
PathContainer.cpp PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp Shape.cpp
ShapeContainer.cpp ShapeContainer.cpp
VectorPath.cpp VectorPath.cpp
+18 -8
View File
@@ -1,9 +1,10 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006, 2023, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "Icon.h" #include "Icon.h"
@@ -12,6 +13,8 @@
#include <stdio.h> #include <stdio.h>
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "ReferenceImage.h"
#include "Shape.h" #include "Shape.h"
#include "Style.h" #include "Style.h"
#include "StyleContainer.h" #include "StyleContainer.h"
@@ -79,21 +82,27 @@ Icon::Icon(const Icon& other)
int32 shapeCount = other.fShapes->CountShapes(); int32 shapeCount = other.fShapes->CountShapes();
for (int32 i = 0; i < shapeCount; i++) { for (int32 i = 0; i < shapeCount; i++) {
Shape* shape = other.fShapes->ShapeAtFast(i); Shape* shape = other.fShapes->ShapeAtFast(i);
Shape* clone = new (nothrow) Shape(*shape); Shape* clone = shape->Clone();
if (!clone || !fShapes->AddShape(clone)) { if (!clone || !fShapes->AddShape(clone)) {
delete clone; delete clone;
return; 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 cloned shape references styles and paths in
// the "other" icon, replace them with "local" styles // the "other" icon, replace them with "local" styles
// and paths // and paths
int32 styleIndex = other.fStyles->IndexOf(shape->Style());
clone->SetStyle(fStyles->StyleAt(styleIndex));
clone->Paths()->MakeEmpty(); int32 styleIndex = other.fStyles->IndexOf(pathSourceShape->Style());
pathCount = shape->Paths()->CountPaths(); pathSourceShapeClone->SetStyle(fStyles->StyleAt(styleIndex));
pathSourceShapeClone->Paths()->MakeEmpty();
pathCount = pathSourceShape->Paths()->CountPaths();
for (int32 j = 0; j < pathCount; j++) { for (int32 j = 0; j < pathCount; j++) {
VectorPath* remote = shape->Paths()->PathAtFast(j); VectorPath* remote = pathSourceShape->Paths()->PathAtFast(j);
int32 index = other.fPaths->IndexOf(remote); int32 index = other.fPaths->IndexOf(remote);
VectorPath* local = fPaths->PathAt(index); VectorPath* local = fPaths->PathAt(index);
if (!local) { if (!local) {
@@ -101,12 +110,13 @@ Icon::Icon(const Icon& other)
"local paths while cloning icon\n"); "local paths while cloning icon\n");
continue; continue;
} }
if (!clone->Paths()->AddPath(local)) { if (!pathSourceShapeClone->Paths()->AddPath(local)) {
return; return;
} }
} }
} }
} }
}
// destructor // destructor
Icon::~Icon() Icon::~Icon()
+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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "IconRenderer.h" #include "IconRenderer.h"
#include <algorithm>
#include <new> #include <new>
#include <stdio.h> #include <stdio.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <List.h> #include <List.h>
#include <agg_image_accessors.h>
#include <agg_span_image_filter_rgba.h>
#include <agg_span_gradient.h> #include <agg_span_gradient.h>
#include <agg_span_interpolator_linear.h> #include <agg_span_interpolator_linear.h>
@@ -33,12 +37,22 @@ class IconRenderer::StyleHandler {
}; };
public: 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) StyleHandler(::GammaTable& gammaTable)
: fStyles(20), : fStyles(20),
fGammaTable(gammaTable), fGammaTable(gammaTable),
fTransparent(0, 0, 0, 0), fTransparent(0, 0, 0, 0),
fColor(0, 0, 0, 0) fColor(0, 0, 0, 0)
{} {}
#endif // ICON_O_MATIC
~StyleHandler() ~StyleHandler()
{ {
@@ -53,7 +67,15 @@ class IconRenderer::StyleHandler {
if (!styleItem) if (!styleItem)
return true; 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); const agg::rgba8& color(unsigned styleIndex);
@@ -86,14 +108,21 @@ private:
void _GenerateGradient(agg::rgba8* span, int x, int y, unsigned len, void _GenerateGradient(agg::rgba8* span, int x, int y, unsigned len,
GradientFunction function, int32 start, int32 end, GradientFunction function, int32 start, int32 end,
const agg::rgba8* gradientColors, Transformation& gradientTransform); 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; BList fStyles;
::GammaTable& fGammaTable; ::GammaTable& fGammaTable;
#ifdef ICON_O_MATIC
bool fShowReferences;
#endif
agg::rgba8 fTransparent; agg::rgba8 fTransparent;
agg::rgba8 fColor; agg::rgba8 fColor;
}; };
// color
const agg::rgba8& const agg::rgba8&
IconRenderer::StyleHandler::color(unsigned styleIndex) IconRenderer::StyleHandler::color(unsigned styleIndex)
{ {
@@ -103,6 +132,13 @@ IconRenderer::StyleHandler::color(unsigned styleIndex)
return fTransparent; 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(); const rgb_color& c = styleItem->style->Color();
fColor = agg::rgba8(fGammaTable.dir(c.red), fGammaTable.dir(c.green), fColor = agg::rgba8(fGammaTable.dir(c.red), fGammaTable.dir(c.green),
fGammaTable.dir(c.blue), c.alpha); fGammaTable.dir(c.blue), c.alpha);
@@ -110,18 +146,30 @@ IconRenderer::StyleHandler::color(unsigned styleIndex)
return fColor; return fColor;
} }
// generate_span
void void
IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y, IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
unsigned len, unsigned styleIndex) unsigned len, unsigned styleIndex)
{ {
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(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); printf("no style/gradient at index: %u!\n", styleIndex);
// TODO: memset() span? // TODO: memset() span?
return; 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; Style* style = styleItem->style;
Gradient* gradient = style->Gradient(); Gradient* gradient = style->Gradient();
const agg::rgba8* colors = style->GammaCorrectedColors(fGammaTable); 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> template<class GradientFunction>
void void
IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y, 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); 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 - // #pragma mark -
class HintingTransformer { class HintingTransformer {
public: public:
@@ -204,7 +295,7 @@ class HintingTransformer {
// #pragma mark - // #pragma mark -
// constructor
IconRenderer::IconRenderer(BBitmap* bitmap) IconRenderer::IconRenderer(BBitmap* bitmap)
: fBitmap(bitmap), : fBitmap(bitmap),
fBackground(NULL), fBackground(NULL),
@@ -236,12 +327,12 @@ IconRenderer::IconRenderer(BBitmap* bitmap)
bitmap->Bounds().IntegerHeight()); bitmap->Bounds().IntegerHeight());
} }
// destructor
IconRenderer::~IconRenderer() IconRenderer::~IconRenderer()
{ {
} }
// SetIcon
void void
IconRenderer::SetIcon(const Icon* icon) IconRenderer::SetIcon(const Icon* icon)
{ {
@@ -252,21 +343,37 @@ IconRenderer::SetIcon(const Icon* icon)
// TODO: ... ? // TODO: ... ?
} }
// Render
void void
#ifdef ICON_O_MATIC
IconRenderer::Render(bool showReferences)
#else
IconRenderer::Render() IconRenderer::Render()
#endif
{ {
#ifdef ICON_O_MATIC
_Render(fBitmap->Bounds(), showReferences);
#else
_Render(fBitmap->Bounds()); _Render(fBitmap->Bounds());
#endif
} }
// Render
void void
#ifdef ICON_O_MATIC
IconRenderer::Render(const BRect& area, bool showReferences)
#else
IconRenderer::Render(const BRect& area) IconRenderer::Render(const BRect& area)
#endif
{ {
#ifdef ICON_O_MATIC
_Render(fBitmap->Bounds() & area, showReferences);
#else
_Render(fBitmap->Bounds() & area); _Render(fBitmap->Bounds() & area);
#endif
} }
//SetScale
void void
IconRenderer::SetScale(double scale) IconRenderer::SetScale(double scale)
{ {
@@ -274,14 +381,14 @@ IconRenderer::SetScale(double scale)
fGlobalTransform.multiply(agg::trans_affine_scaling(scale)); fGlobalTransform.multiply(agg::trans_affine_scaling(scale));
} }
//SetBackground
void void
IconRenderer::SetBackground(const BBitmap* background) IconRenderer::SetBackground(const BBitmap* background)
{ {
fBackground = background; fBackground = background;
} }
//SetBackground
void void
IconRenderer::SetBackground(const agg::rgba8& background) IconRenderer::SetBackground(const agg::rgba8& background)
{ {
@@ -291,7 +398,7 @@ IconRenderer::SetBackground(const agg::rgba8& background)
fBackgroundColor.a = background.a; fBackgroundColor.a = background.a;
} }
// Demultiply
void void
IconRenderer::Demultiply() IconRenderer::Demultiply()
{ {
@@ -314,14 +421,20 @@ IconRenderer::Demultiply()
} }
} }
// #pragma mark - // #pragma mark -
typedef agg::conv_transform<VertexSource, Transformation> ScaledPath; typedef agg::conv_transform<VertexSource, Transformation> ScaledPath;
typedef agg::conv_transform<ScaledPath, HintingTransformer> HintedPath; typedef agg::conv_transform<ScaledPath, HintingTransformer> HintedPath;
// _Render
void void
#ifdef ICON_O_MATIC
IconRenderer::_Render(const BRect& r, bool showReferences)
#else
IconRenderer::_Render(const BRect& r) IconRenderer::_Render(const BRect& r)
#endif
{ {
if (!fIcon) if (!fIcon)
return; return;
@@ -336,7 +449,11 @@ IconRenderer::_Render(const BRect& r)
fBaseRendererPre.clear(fBackgroundColor); fBaseRendererPre.clear(fBackgroundColor);
//bigtime_t start = system_time(); //bigtime_t start = system_time();
#ifdef ICON_O_MATIC
StyleHandler styleHandler(fGammaTable, showReferences);
#else
StyleHandler styleHandler(fGammaTable); StyleHandler styleHandler(fGammaTable);
#endif
fRasterizer.reset(); fRasterizer.reset();
// iterate over the shapes in the icon, // iterate over the shapes in the icon,
@@ -347,12 +464,7 @@ IconRenderer::_Render(const BRect& r)
for (int32 i = 0; i < shapeCount; i++) { for (int32 i = 0; i < shapeCount; i++) {
Shape* shape = fIcon->Shapes()->ShapeAtFast(i); Shape* shape = fIcon->Shapes()->ShapeAtFast(i);
// Don't render shape if the Level Of Detail falls out of range. if (!shape->Visible(fGlobalTransform.scale())) {
// 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)) {
continue; continue;
} }
@@ -385,7 +497,12 @@ IconRenderer::_Render(const BRect& r)
// if this is not the first shape, and the style contains // if this is not the first shape, and the style contains
// transparency, commit a render pass of previous shapes // 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); _CommitRenderPass(styleHandler);
fRasterizer.styles(styleIndex, -1); fRasterizer.styles(styleIndex, -1);
@@ -413,7 +530,7 @@ IconRenderer::_Render(const BRect& r)
//printf("rendering 64x64: %lld\n", system_time() - start); //printf("rendering 64x64: %lld\n", system_time() - start);
} }
// _CommitRenderPass
void void
IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset) IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset)
{ {
@@ -424,6 +541,3 @@ IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset)
fRasterizer.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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#ifndef ICON_RENDERER_H #ifndef ICON_RENDERER_H
#define ICON_RENDERER_H #define ICON_RENDERER_H
@@ -55,8 +56,13 @@ class IconRenderer {
void SetIcon(const Icon* icon); 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();
void Render(const BRect& area); void Render(const BRect& area);
#endif // ICON_O_MATIC
void SetScale(double scale); void SetScale(double scale);
void SetBackground(const BBitmap* background); void SetBackground(const BBitmap* background);
@@ -77,7 +83,11 @@ class IconRenderer {
private: private:
class StyleHandler; class StyleHandler;
#ifdef ICON_O_MATIC
void _Render(const BRect& area, bool showReferences);
#else
void _Render(const BRect& area); void _Render(const BRect& area);
#endif // ICON_O_MATIC
void _CommitRenderPass(StyleHandler& styleHandler, void _CommitRenderPass(StyleHandler& styleHandler,
bool reset = true); bool reset = true);
+2
View File
@@ -45,6 +45,8 @@ for architectureObject in [ MultiArchSubDirSetup ] {
# shape # shape
PathContainer.cpp PathContainer.cpp
PathSourceShape.cpp
ReferenceImage.cpp
Shape.cpp Shape.cpp
ShapeContainer.cpp ShapeContainer.cpp
VectorPath.cpp VectorPath.cpp
+2 -1
View File
@@ -24,6 +24,7 @@
#include "LittleEndianBuffer.h" #include "LittleEndianBuffer.h"
#include "PathCommandQueue.h" #include "PathCommandQueue.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#include "PerspectiveTransformer.h" #include "PerspectiveTransformer.h"
#include "Shape.h" #include "Shape.h"
#include "StrokeTransformer.h" #include "StrokeTransformer.h"
@@ -543,7 +544,7 @@ FlatIconImporter::_ReadPathSourceShape(LittleEndianBuffer& buffer,
} }
// create the shape // create the shape
Shape* shape = new (nothrow) Shape(style); PathSourceShape* shape = new (nothrow) PathSourceShape(style);
ObjectDeleter<Shape> shapeDeleter(shape); ObjectDeleter<Shape> shapeDeleter(shape);
if (!shape || shape->InitCheck() < B_OK) if (!shape || shape->InitCheck() < B_OK)
+29 -5
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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
@@ -13,6 +14,9 @@
#include <stdio.h> #include <stdio.h>
#include <Archivable.h> #include <Archivable.h>
#ifdef ICON_O_MATIC
#include <Bitmap.h>
#endif
#include <ByteOrder.h> #include <ByteOrder.h>
#include <DataIO.h> #include <DataIO.h>
#include <Message.h> #include <Message.h>
@@ -20,6 +24,10 @@
#include "Defines.h" #include "Defines.h"
#include "Icon.h" #include "Icon.h"
#include "PathContainer.h" #include "PathContainer.h"
#include "PathSourceShape.h"
#ifdef ICON_O_MATIC
#include "ReferenceImage.h"
#endif
#include "Shape.h" #include "Shape.h"
#include "Style.h" #include "Style.h"
#include "StyleContainer.h" #include "StyleContainer.h"
@@ -178,6 +186,12 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
BMessage shapeArchive; BMessage shapeArchive;
for (int32 i = 0; for (int32 i = 0;
allShapes.FindMessage("shape", i, &shapeArchive) == B_OK; i++) { allShapes.FindMessage("shape", i, &shapeArchive) == B_OK; i++) {
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
// find the right style // find the right style
int32 styleIndex; int32 styleIndex;
if (shapeArchive.FindInt32("style ref", &styleIndex) < B_OK) { if (shapeArchive.FindInt32("style ref", &styleIndex) < B_OK) {
@@ -190,7 +204,7 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
#else #else
Style* style = styles->StyleAt(styleIndex); Style* style = styles->StyleAt(styleIndex);
#endif #endif
if (!style) { if (style == NULL) {
printf("MessageImporter::_ImportShapes() - " printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " wants Style %" B_PRId32 ", which does not exist\n", "Shape %" B_PRId32 " wants Style %" B_PRId32 ", which does not exist\n",
i, styleIndex); i, styleIndex);
@@ -198,8 +212,8 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
} }
// create shape // create shape
Shape* shape = new (nothrow) Shape(style); PathSourceShape* shape = new (nothrow) PathSourceShape(style);
if (!shape || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) { if (shape == NULL || shape->InitCheck() < B_OK || !shapes->AddShape(shape)) {
delete shape; delete shape;
ret = B_NO_MEMORY; ret = B_NO_MEMORY;
} }
@@ -216,7 +230,7 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
#else #else
VectorPath* path = paths->PathAt(pathIndex); VectorPath* path = paths->PathAt(pathIndex);
#endif #endif
if (!path) { if (path == NULL) {
printf("MessageImporter::_ImportShapes() - " printf("MessageImporter::_ImportShapes() - "
"Shape %" B_PRId32 " referenced path %" B_PRId32 ", " "Shape %" B_PRId32 " referenced path %" B_PRId32 ", "
"which does not exist\n", i, pathIndex); "which does not exist\n", i, pathIndex);
@@ -229,6 +243,16 @@ MessageImporter::_ImportShapes(const BMessage* archive, PathContainer* paths,
if (ret == B_OK) if (ret == B_OK)
shape->Unarchive(&shapeArchive); 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; 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
+72 -145
View File
@@ -27,21 +27,22 @@
using std::nothrow; using std::nothrow;
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
// constructor
ShapeListener::ShapeListener() ShapeListener::ShapeListener()
{ {
} }
// destructor
ShapeListener::~ShapeListener() ShapeListener::~ShapeListener()
{ {
} }
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
// #pragma mark - // #pragma mark -
// constructor
Shape::Shape(::Style* style) Shape::Shape(::Style* style)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
: IconObject("<shape>"), : IconObject("<shape>"),
@@ -61,9 +62,7 @@ Shape::Shape(::Style* style)
fLastBounds(0, 0, -1, -1), fLastBounds(0, 0, -1, -1),
fHinting(false), fHinting(false)
fMinVisibilityScale(0.0),
fMaxVisibilityScale(4.0)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
, fListeners(8) , fListeners(8)
@@ -77,7 +76,7 @@ Shape::Shape(::Style* style)
#endif #endif
} }
// constructor
Shape::Shape(const Shape& other) Shape::Shape(const Shape& other)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
: IconObject(other), : IconObject(other),
@@ -97,9 +96,7 @@ Shape::Shape(const Shape& other)
fLastBounds(0, 0, -1, -1), fLastBounds(0, 0, -1, -1),
fHinting(other.fHinting), fHinting(false)
fMinVisibilityScale(other.fMinVisibilityScale),
fMaxVisibilityScale(other.fMaxVisibilityScale)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
, fListeners(8) , fListeners(8)
@@ -111,6 +108,7 @@ Shape::Shape(const Shape& other)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
fPaths->AddListener(this); fPaths->AddListener(this);
#endif #endif
// copy the path references from // copy the path references from
// the other shape // the other shape
if (other.fPaths) { if (other.fPaths) {
@@ -133,7 +131,7 @@ Shape::Shape(const Shape& other)
} }
} }
// destructor
Shape::~Shape() Shape::~Shape()
{ {
int32 count = fTransformers.CountItems(); int32 count = fTransformers.CountItems();
@@ -155,11 +153,12 @@ Shape::~Shape()
SetStyle(NULL); SetStyle(NULL);
} }
// #pragma mark - // #pragma mark -
// Unarchive
status_t status_t
Shape::Unarchive(const BMessage* archive) Shape::Unarchive(BMessage* archive)
{ {
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
// IconObject properties // IconObject properties
@@ -170,6 +169,10 @@ Shape::Unarchive(const BMessage* archive)
status_t ret; status_t ret;
#endif #endif
// hinting
if (archive->FindBool("hinting", &fHinting) < B_OK)
fHinting = false;
// recreate transformers // recreate transformers
BMessage transformerArchive; BMessage transformerArchive;
for (int32 i = 0; for (int32 i = 0;
@@ -193,40 +196,20 @@ Shape::Unarchive(const BMessage* archive)
if (ret == B_OK && dataSize == (ssize_t)(size * sizeof(double))) if (ret == B_OK && dataSize == (ssize_t)(size * sizeof(double)))
LoadFrom((const double*)matrix); 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; return B_OK;
} }
#ifdef ICON_O_MATIC
// Archive #ifdef ICON_O_MATIC
status_t status_t
Shape::Archive(BMessage* into, bool deep) const Shape::Archive(BMessage* into, bool deep) const
{ {
status_t ret = IconObject::Archive(into, deep); status_t ret = IconObject::Archive(into, deep);
// hinting
if (ret == B_OK)
ret = into->AddBool("hinting", fHinting);
// transformers // transformers
if (ret == B_OK) { if (ret == B_OK) {
int32 count = CountTransformers(); int32 count = CountTransformers();
@@ -250,66 +233,29 @@ Shape::Archive(BMessage* into, bool deep) const
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; return ret;
} }
// MakePropertyObject
PropertyObject* PropertyObject*
Shape::MakePropertyObject() const Shape::MakePropertyObject() const
{ {
PropertyObject* object = IconObject::MakePropertyObject(); 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; return object;
} }
// SetToPropertyObject
bool bool
Shape::SetToPropertyObject(const PropertyObject* object) Shape::SetToPropertyObject(const PropertyObject* object)
{ {
AutoNotificationSuspender _(this);
IconObject::SetToPropertyObject(object); IconObject::SetToPropertyObject(object);
return true;
// 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();
} }
// #pragma mark - // #pragma mark -
// TransformationChanged
void void
Shape::TransformationChanged() Shape::TransformationChanged()
{ {
@@ -317,9 +263,10 @@ Shape::TransformationChanged()
_NotifyRerender(); _NotifyRerender();
} }
// #pragma mark - // #pragma mark -
// ObjectChanged
void void
Shape::ObjectChanged(const Observable* object) Shape::ObjectChanged(const Observable* object)
{ {
@@ -329,9 +276,10 @@ Shape::ObjectChanged(const Observable* object)
_NotifyRerender(); _NotifyRerender();
} }
// #pragma mark - // #pragma mark -
// PathAdded
void void
Shape::PathAdded(VectorPath* path, int32 index) Shape::PathAdded(VectorPath* path, int32 index)
{ {
@@ -340,7 +288,7 @@ Shape::PathAdded(VectorPath* path, int32 index)
_NotifyRerender(); _NotifyRerender();
} }
// PathRemoved
void void
Shape::PathRemoved(VectorPath* path) Shape::PathRemoved(VectorPath* path)
{ {
@@ -349,65 +297,66 @@ Shape::PathRemoved(VectorPath* path)
path->ReleaseReference(); path->ReleaseReference();
} }
// #pragma mark - // #pragma mark -
// PointAdded
void void
Shape::PointAdded(int32 index) Shape::PointAdded(int32 index)
{ {
_NotifyRerender(); _NotifyRerender();
} }
// PointRemoved
void void
Shape::PointRemoved(int32 index) Shape::PointRemoved(int32 index)
{ {
_NotifyRerender(); _NotifyRerender();
} }
// PointChanged
void void
Shape::PointChanged(int32 index) Shape::PointChanged(int32 index)
{ {
_NotifyRerender(); _NotifyRerender();
} }
// PathChanged
void void
Shape::PathChanged() Shape::PathChanged()
{ {
_NotifyRerender(); _NotifyRerender();
} }
// PathClosedChanged
void void
Shape::PathClosedChanged() Shape::PathClosedChanged()
{ {
_NotifyRerender(); _NotifyRerender();
} }
// PathReversed
void void
Shape::PathReversed() Shape::PathReversed()
{ {
_NotifyRerender(); _NotifyRerender();
} }
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
// #pragma mark - // #pragma mark -
// InitCheck
status_t status_t
Shape::InitCheck() const Shape::InitCheck() const
{ {
return fPaths ? B_OK : B_NO_MEMORY; return fPaths ? B_OK : B_NO_MEMORY;
} }
// #pragma mark - // #pragma mark -
// SetStyle
void void
Shape::SetStyle(::Style* style) Shape::SetStyle(::Style* style)
{ {
@@ -434,9 +383,10 @@ Shape::SetStyle(::Style* style)
#endif #endif
} }
// #pragma mark - // #pragma mark -
// Bounds
BRect BRect
Shape::Bounds(bool updateLast) const Shape::Bounds(bool updateLast) const
{ {
@@ -464,7 +414,7 @@ Shape::Bounds(bool updateLast) const
return bounds; return bounds;
} }
// VertexSource
::VertexSource& ::VertexSource&
Shape::VertexSource() Shape::VertexSource()
{ {
@@ -486,21 +436,21 @@ Shape::VertexSource()
return *source; return *source;
} }
// SetGlobalScale
void void
Shape::SetGlobalScale(double scale) Shape::SetGlobalScale(double scale)
{ {
fPathSource.SetGlobalScale(scale); fPathSource.SetGlobalScale(scale);
} }
// AddTransformer
bool bool
Shape::AddTransformer(Transformer* transformer) Shape::AddTransformer(Transformer* transformer)
{ {
return AddTransformer(transformer, CountTransformers()); return AddTransformer(transformer, CountTransformers());
} }
// AddTransformer
bool bool
Shape::AddTransformer(Transformer* transformer, int32 index) Shape::AddTransformer(Transformer* transformer, int32 index)
{ {
@@ -520,7 +470,7 @@ Shape::AddTransformer(Transformer* transformer, int32 index)
return true; return true;
} }
// RemoveTransformer
bool bool
Shape::RemoveTransformer(Transformer* transformer) Shape::RemoveTransformer(Transformer* transformer)
{ {
@@ -538,83 +488,49 @@ Shape::RemoveTransformer(Transformer* transformer)
return false; return false;
} }
// #pragma mark - // #pragma mark -
// CountShapes
int32 int32
Shape::CountTransformers() const Shape::CountTransformers() const
{ {
return fTransformers.CountItems(); return fTransformers.CountItems();
} }
// HasTransformer
bool bool
Shape::HasTransformer(Transformer* transformer) const Shape::HasTransformer(Transformer* transformer) const
{ {
return fTransformers.HasItem((void*)transformer); return fTransformers.HasItem((void*)transformer);
} }
// IndexOf
int32 int32
Shape::IndexOf(Transformer* transformer) const Shape::IndexOf(Transformer* transformer) const
{ {
return fTransformers.IndexOf((void*)transformer); return fTransformers.IndexOf((void*)transformer);
} }
// TransformerAt
Transformer* Transformer*
Shape::TransformerAt(int32 index) const Shape::TransformerAt(int32 index) const
{ {
return (Transformer*)fTransformers.ItemAt(index); return (Transformer*)fTransformers.ItemAt(index);
} }
// TransformerAtFast
Transformer* Transformer*
Shape::TransformerAtFast(int32 index) const Shape::TransformerAtFast(int32 index) const
{ {
return (Transformer*)fTransformers.ItemAtFast(index); 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 - // #pragma mark -
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
// AddListener
bool bool
Shape::AddListener(ShapeListener* listener) Shape::AddListener(ShapeListener* listener)
{ {
@@ -623,16 +539,17 @@ Shape::AddListener(ShapeListener* listener)
return false; return false;
} }
// RemoveListener
bool bool
Shape::RemoveListener(ShapeListener* listener) Shape::RemoveListener(ShapeListener* listener)
{ {
return fListeners.RemoveItem((void*)listener); return fListeners.RemoveItem((void*)listener);
} }
// #pragma mark - // #pragma mark -
// _NotifyTransformerAdded
void void
Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
{ {
@@ -647,7 +564,7 @@ Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
_NotifyRerender(); _NotifyRerender();
} }
// _NotifyTransformerRemoved
void void
Shape::_NotifyTransformerRemoved(Transformer* transformer) const Shape::_NotifyTransformerRemoved(Transformer* transformer) const
{ {
@@ -662,7 +579,7 @@ Shape::_NotifyTransformerRemoved(Transformer* transformer) const
_NotifyRerender(); _NotifyRerender();
} }
// _NotifyStyleChanged
void void
Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const
{ {
@@ -677,13 +594,23 @@ Shape::_NotifyStyleChanged(::Style* oldStyle, ::Style* newStyle) const
_NotifyRerender(); _NotifyRerender();
} }
// _NotifyRerender
void void
Shape::_NotifyRerender() const Shape::_NotifyRerender() const
{ {
fNeedsUpdate = true; fNeedsUpdate = true;
Notify(); Notify();
} }
#endif // ICON_O_MATIC #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> #include <Rect.h>
class BMessage;
_BEGIN_ICON_NAMESPACE _BEGIN_ICON_NAMESPACE
class Style; class Style;
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
// TODO: merge Observer and ShapeListener interface // TODO: merge Observer and ShapeListener interface
// ie add "AppearanceChanged(Shape* shape)" // ie add "AppearanceChanged(Shape* shape)"
@@ -40,6 +42,7 @@ class ShapeListener {
int32 index) = 0; int32 index) = 0;
virtual void TransformerRemoved(Transformer* t) = 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, virtual void StyleChanged(::Style* oldStyle,
::Style* newStyle) = 0; ::Style* newStyle) = 0;
}; };
@@ -61,7 +64,7 @@ class Shape : public _ICON_NAMESPACE Transformable {
virtual ~Shape(); virtual ~Shape();
// IconObject interface // IconObject interface
virtual status_t Unarchive(const BMessage* archive); virtual status_t Unarchive(BMessage* archive);
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
virtual status_t Archive(BMessage* into, virtual status_t Archive(BMessage* into,
bool deep = true) const; bool deep = true) const;
@@ -92,12 +95,13 @@ class Shape : public _ICON_NAMESPACE Transformable {
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
// Shape // Shape
status_t InitCheck() const; virtual status_t InitCheck() const;
virtual Shape* Clone() const = 0;
inline PathContainer* Paths() const inline PathContainer* Paths() const
{ return fPaths; } { return fPaths; }
void SetStyle(::Style* style); public:
inline ::Style* Style() const inline ::Style* Style() const
{ return fStyle; } { return fStyle; }
@@ -124,12 +128,8 @@ class Shape : public _ICON_NAMESPACE Transformable {
void SetHinting(bool hinting); void SetHinting(bool hinting);
bool Hinting() const bool Hinting() const
{ return fHinting; } { return fHinting; }
void SetMinVisibilityScale(float scale);
float MinVisibilityScale() const virtual bool Visible(float scale) const = 0;
{ return fMinVisibilityScale; }
void SetMaxVisibilityScale(float scale);
float MaxVisibilityScale() const
{ return fMaxVisibilityScale; }
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
bool AddListener(ShapeListener* listener); bool AddListener(ShapeListener* listener);
@@ -146,6 +146,9 @@ class Shape : public _ICON_NAMESPACE Transformable {
void _NotifyRerender() const; void _NotifyRerender() const;
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
protected:
void SetStyle(::Style* style);
private: private:
PathContainer* fPaths; PathContainer* fPaths;
::Style* fStyle; ::Style* fStyle;
@@ -157,15 +160,12 @@ class Shape : public _ICON_NAMESPACE Transformable {
mutable BRect fLastBounds; mutable BRect fLastBounds;
bool fHinting; bool fHinting;
float fMinVisibilityScale;
float fMaxVisibilityScale;
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
BList fListeners; BList fListeners;
#endif #endif
}; };
_END_ICON_NAMESPACE _END_ICON_NAMESPACE
+77 -14
View File
@@ -1,15 +1,17 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006, 2023, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#include "Style.h" #include "Style.h"
#include <new> #include <new>
#include <Bitmap.h>
#include <Message.h> #include <Message.h>
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
@@ -22,7 +24,7 @@
using std::nothrow; using std::nothrow;
// constructor
Style::Style() Style::Style()
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
: IconObject("<style>"), : IconObject("<style>"),
@@ -34,13 +36,17 @@ Style::Style()
fColor(kWhite), fColor(kWhite),
fGradient(NULL), fGradient(NULL),
fColors(NULL), fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL), fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false) fGammaCorrectedColorsValid(false)
{ {
} }
// constructor
Style::Style(const rgb_color& color) Style::Style(const rgb_color& color)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
: IconObject("<style>"), : IconObject("<style>"),
@@ -52,13 +58,34 @@ Style::Style(const rgb_color& color)
fColor(color), fColor(color),
fGradient(NULL), fGradient(NULL),
fColors(NULL), fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL), fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false) 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) Style::Style(const Style& other)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
: IconObject(other), : IconObject(other),
@@ -70,6 +97,10 @@ Style::Style(const Style& other)
fColor(other.fColor), fColor(other.fColor),
fGradient(NULL), fGradient(NULL),
fColors(NULL), fColors(NULL),
#ifdef ICON_O_MATIC
fImage(other.fImage != NULL ? new (nothrow) BBitmap(other.fImage) : NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL), fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false) fGammaCorrectedColorsValid(false)
@@ -89,6 +120,10 @@ Style::Style(BMessage* archive)
fColor(kWhite), fColor(kWhite),
fGradient(NULL), fGradient(NULL),
fColors(NULL), fColors(NULL),
#ifdef ICON_O_MATIC
fImage(NULL),
fAlpha(255),
#endif
fGammaCorrectedColors(NULL), fGammaCorrectedColors(NULL),
fGammaCorrectedColorsValid(false) fGammaCorrectedColorsValid(false)
@@ -106,14 +141,18 @@ Style::Style(BMessage* archive)
} }
} }
// destructor
Style::~Style() Style::~Style()
{ {
SetGradient(NULL); SetGradient(NULL);
}
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
// ObjectChanged delete fImage;
#endif
}
#ifdef ICON_O_MATIC
void void
Style::ObjectChanged(const Observable* object) Style::ObjectChanged(const Observable* object)
{ {
@@ -124,9 +163,10 @@ Style::ObjectChanged(const Observable* object)
} }
} }
// #pragma mark - // #pragma mark -
// Archive
status_t status_t
Style::Archive(BMessage* into, bool deep) const Style::Archive(BMessage* into, bool deep) const
{ {
@@ -142,10 +182,12 @@ Style::Archive(BMessage* into, bool deep) const
ret = into->AddMessage("gradient", &gradientArchive); ret = into->AddMessage("gradient", &gradientArchive);
} }
// Archiving the fImage is the responsibility of ReferenceImage
return ret; return ret;
} }
// operator ==
bool bool
Style::operator==(const Style& other) const Style::operator==(const Style& other) const
{ {
@@ -161,10 +203,9 @@ Style::operator==(const Style& other) const
return false; return false;
} }
} }
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
// HasTransparency
bool bool
Style::HasTransparency() const Style::HasTransparency() const
{ {
@@ -180,7 +221,7 @@ Style::HasTransparency() const
return fColor.alpha < 255; return fColor.alpha < 255;
} }
// SetColor
void void
Style::SetColor(const rgb_color& color) Style::SetColor(const rgb_color& color)
{ {
@@ -191,7 +232,7 @@ Style::SetColor(const rgb_color& color)
Notify(); Notify();
} }
// SetGradient
void void
Style::SetGradient(const ::Gradient* gradient) Style::SetGradient(const ::Gradient* gradient)
{ {
@@ -226,6 +267,9 @@ Style::SetGradient(const ::Gradient* gradient)
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
if (fGradient != NULL) if (fGradient != NULL)
fGradient->ReleaseReference(); fGradient->ReleaseReference();
delete fImage;
fImage = NULL;
#else #else
delete fGradient; delete fGradient;
#endif #endif
@@ -236,7 +280,26 @@ Style::SetGradient(const ::Gradient* gradient)
} }
} }
// GammaCorrectedColors
#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* const agg::rgba8*
Style::GammaCorrectedColors(const GammaTable& table) const Style::GammaCorrectedColors(const GammaTable& table) const
{ {
+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. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Zardshard
*/ */
#ifndef STYLE_H #ifndef STYLE_H
#define STYLE_H #define STYLE_H
@@ -30,7 +31,10 @@ _BEGIN_ICON_NAMESPACE
class Gradient; 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 #ifdef ICON_O_MATIC
class Style : public IconObject, class Style : public IconObject,
public Observer { public Observer {
@@ -41,6 +45,10 @@ class Style {
Style(); Style();
Style(const Style& other); Style(const Style& other);
Style(const rgb_color& color); Style(const rgb_color& color);
#ifdef ICON_O_MATIC
Style(BBitmap* image);
// transfers ownership of the image
#endif
Style(BMessage* archive); Style(BMessage* archive);
virtual ~Style(); virtual ~Style();
@@ -69,6 +77,19 @@ class Style {
_ICON_NAMESPACE Gradient* Gradient() const _ICON_NAMESPACE Gradient* Gradient() const
{ return fGradient; } { 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 const agg::rgba8* Colors() const
{ return fColors; } { return fColors; }
@@ -77,11 +98,17 @@ class Style {
private: private:
rgb_color fColor; rgb_color fColor;
_ICON_NAMESPACE Gradient* fGradient; _ICON_NAMESPACE Gradient* fGradient;
// hold gradient color array // hold gradient color array
agg::rgba8* fColors; agg::rgba8* fColors;
#ifdef ICON_O_MATIC
BBitmap* fImage;
uint8 fAlpha;
#endif
// for caching gamma corrected gradient color array // for caching gamma corrected gradient color array
mutable agg::rgba8* fGammaCorrectedColors; mutable agg::rgba8* fGammaCorrectedColors;
mutable bool fGammaCorrectedColorsValid; mutable bool fGammaCorrectedColorsValid;
@@ -16,9 +16,6 @@
#ifdef ICON_O_MATIC #ifdef ICON_O_MATIC
#include <Catalog.h> #include <Catalog.h>
#include <Message.h> #include <Message.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Transformation"
#endif #endif
@@ -30,13 +27,13 @@ Transformer*
TransformerFactory::TransformerFor(uint32 type, VertexSource& source) TransformerFactory::TransformerFor(uint32 type, VertexSource& source)
{ {
switch (type) { switch (type) {
case 0: case AFFINE_TRANSFORMER:
return new AffineTransformer(source); return new AffineTransformer(source);
case 1: case PERSPECTIVE_TRANSFORMER:
return new PerspectiveTransformer(source); return new PerspectiveTransformer(source);
case 2: case CONTOUR_TRANSFORMER:
return new ContourTransformer(source); return new ContourTransformer(source);
case 3: case STROKE_TRANSFORMER:
return new StrokeTransformer(source); return new StrokeTransformer(source);
} }
@@ -62,30 +59,3 @@ TransformerFactory::TransformerFor(BMessage* message,
return NULL; 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 Transformer;
class VertexSource; class VertexSource;
enum {
AFFINE_TRANSFORMER,
PERSPECTIVE_TRANSFORMER,
CONTOUR_TRANSFORMER,
STROKE_TRANSFORMER,
};
class TransformerFactory { class TransformerFactory {
public: public:
@@ -31,13 +39,6 @@ class TransformerFactory {
static Transformer* TransformerFor(BMessage* archive, static Transformer* TransformerFor(BMessage* archive,
VertexSource& source); VertexSource& source);
#ifdef ICON_O_MATIC
static bool NextType(int32* cookie,
uint32* type,
BString* name);
#endif // ICON_O_MATIC
}; };