From 0199e126e25c794f4a3ec7765a29a49d4bbbabcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 21 Jun 2006 14:38:13 +0000 Subject: [PATCH] implemented a cool vertex transformation pipeline: * VertexSource virtualizes the AGG "VertexSource" interface * Transformer is an interface for building pipelines of VertexSource objects, each taking the output of the previous object and transforming it in some way * StrokeTransformer is currently the only implementation and converts a path into an outline stroke * PathSource implements the VertexSource interface on top of a VectorPath which it converts into an agg::path_storage and into an agg::conv_curve to get smooth bezier curves * added VertexSource() to Shape class, which returns the last object of the transformation pipeline, it uses a PathSource for the root object * changed IconRenderer to use the new polymorphic VertexSource pipeline git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17896 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/icon-o-matic/Jamfile | 39 ++++++++------ src/apps/icon-o-matic/MainWindow.cpp | 24 +++++++-- .../icon-o-matic/document/IconRenderer.cpp | 15 ++---- src/apps/icon-o-matic/shape/Shape.cpp | 39 +++++++++++++- src/apps/icon-o-matic/shape/Shape.h | 9 ++++ .../icon-o-matic/transformer/PathSource.cpp | 54 +++++++++++++++++++ .../icon-o-matic/transformer/PathSource.h | 39 ++++++++++++++ .../transformer/StrokeTransformer.cpp | 44 +++++++++++++++ .../transformer/StrokeTransformer.h | 31 +++++++++++ .../icon-o-matic/transformer/Transformer.cpp | 53 ++++++++++++++++++ .../icon-o-matic/transformer/Transformer.h | 36 +++++++++++++ 11 files changed, 348 insertions(+), 35 deletions(-) create mode 100644 src/apps/icon-o-matic/transformer/PathSource.cpp create mode 100644 src/apps/icon-o-matic/transformer/PathSource.h create mode 100644 src/apps/icon-o-matic/transformer/StrokeTransformer.cpp create mode 100644 src/apps/icon-o-matic/transformer/StrokeTransformer.h create mode 100644 src/apps/icon-o-matic/transformer/Transformer.cpp create mode 100644 src/apps/icon-o-matic/transformer/Transformer.h diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index c50ce4e1ee..0911991839 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -20,6 +20,7 @@ local sourceDirs = shape shape/commands style + transformer ; local sourceDir ; @@ -31,48 +32,52 @@ for sourceDir in $(sourceDirs) { UseLibraryHeaders agg ; Application Icon-O-Matic : - #document + # document Document.cpp Icon.cpp IconRenderer.cpp - #generic/command + # generic/command Command.cpp CommandStack.cpp Selectable.cpp Selection.cpp - #generic/gui - #generic/gui/panel - #generic/gui/popup_control - #generic/gui/scrollview - #generic/gui/stateview + # generic/gui + # generic/gui/panel + # generic/gui/popup_control + # generic/gui/scrollview + # generic/gui/stateview Manipulator.cpp MultipleManipulatorState.cpp StateView.cpp ViewState.cpp - #generic/listener + # generic/listener Observable.cpp Observer.cpp - #generic/selection - #generic/support + # generic/selection + # generic/support RWLocker.cpp support.cpp - #style - Style.cpp - StyleManager.cpp - #shape + # gradient + Gradient.cpp + # shape PathContainer.cpp PathManipulator.cpp Shape.cpp ShapeContainer.cpp VectorPath.cpp - #shape/commands + # shape/commands AddPointCommand.cpp ChangePointCommand.cpp InsertPointCommand.cpp PathCommand.cpp RemovePointsCommand.cpp - #gradient - Gradient.cpp + # style + Style.cpp + StyleManager.cpp + # transformer + PathSource.cpp + StrokeTransformer.cpp + Transformer.cpp # CanvasView.cpp IconEditorApp.cpp diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index d1edfb6a63..ffa30889ae 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -23,6 +23,7 @@ #include "PathManipulator.h" #include "Shape.h" #include "ShapeContainer.h" +#include "StrokeTransformer.h" #include "Style.h" #include "StyleManager.h" #include "VectorPath.h" @@ -91,21 +92,34 @@ MainWindow::_Init() fDocument->Icon()->Paths()->AddPath(path); - Style* style = new Style(); - style->SetColor((rgb_color){ 255, 0, 0, 255 }); + Style* style1 = new Style(); + style1->SetColor((rgb_color){ 255, 255, 255, 255 }); + + StyleManager::Default()->AddStyle(style1); + + Style* style2 = new Style(); Gradient* gradient = new Gradient(true); gradient->AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0); gradient->AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5); gradient->AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0); - style->SetGradient(gradient); + style2->SetGradient(gradient); - StyleManager::Default()->AddStyle(style); + StyleManager::Default()->AddStyle(style2); - Shape* shape = new Shape(style); + Shape* shape = new Shape(style2); shape->Paths()->AddPath(path); fDocument->Icon()->Shapes()->AddShape(shape); + shape = new Shape(style1); + shape->Paths()->AddPath(path); + StrokeTransformer* transformer + = new StrokeTransformer(shape->VertexSource()); + transformer->width(5.0); + shape->AppendTransformer(transformer); + + fDocument->Icon()->Shapes()->AddShape(shape); + PathManipulator* pathManipulator = new PathManipulator(path); state->AddManipulator(pathManipulator); // ---- diff --git a/src/apps/icon-o-matic/document/IconRenderer.cpp b/src/apps/icon-o-matic/document/IconRenderer.cpp index 8e90962d26..53e021e6cc 100644 --- a/src/apps/icon-o-matic/document/IconRenderer.cpp +++ b/src/apps/icon-o-matic/document/IconRenderer.cpp @@ -13,7 +13,6 @@ #include -#include "agg_conv_curve.h" #include "agg_span_gradient.h" #include "agg_span_interpolator_linear.h" @@ -254,19 +253,11 @@ IconRenderer::_Render(const BRect& r) int32 shapeCount = fIcon->Shapes()->CountShapes(); for (int32 s = 0; s < shapeCount; s++) { Shape* shape = fIcon->Shapes()->ShapeAtFast(s); - agg::path_storage aggPath; - int32 pathCount = shape->Paths()->CountPaths(); - for (int32 p = 0; p < pathCount; p++) { - VectorPath* path = shape->Paths()->PathAtFast(p); - agg::path_storage subPath; - if (path->GetAGGPathStorage(subPath)) { - aggPath.concat_path(subPath); - } - } + int32 styleIndex = fStyles->IndexOf(shape->Style()); fRasterizer.styles(styleIndex, -1); - agg::conv_curve curve(aggPath); - fRasterizer.add_path(curve); + + fRasterizer.add_path(shape->VertexSource()); } StyleHandler styleHandler(fStyles, fGammaTable); diff --git a/src/apps/icon-o-matic/shape/Shape.cpp b/src/apps/icon-o-matic/shape/Shape.cpp index d8aacc9cb4..ce6e5f8c7c 100644 --- a/src/apps/icon-o-matic/shape/Shape.cpp +++ b/src/apps/icon-o-matic/shape/Shape.cpp @@ -14,7 +14,9 @@ Shape::Shape(::Style* style) Referenceable(), PathContainerListener(), fPaths(new (nothrow) PathContainer()), - fStyle(style) + fStyle(style), + fPathSource(fPaths), + fTransformers(4) { if (fPaths) fPaths->AddListener(this); @@ -26,6 +28,10 @@ Shape::Shape(::Style* style) // destructor Shape::~Shape() { + int32 count = fTransformers.CountItems(); + for (int32 i = 0; i < count; i++) + delete (Transformer*)fTransformers.ItemAtFast(i); + fPaths->MakeEmpty(); fPaths->RemoveListener(this); delete fPaths; @@ -87,3 +93,34 @@ Shape::Bounds() const return bounds; } + +// VertexSource +::VertexSource& +Shape::VertexSource() +{ + fPathSource.Update(); + ::VertexSource* source = &fPathSource; + + int32 count = fTransformers.CountItems(); + for (int32 i = 0; i < count; i++) { + Transformer* t = (Transformer*)fTransformers.ItemAtFast(i); + t->SetSource(*source); + source = t; + } + + return *source; +} + +// AppendTransformer +bool +Shape::AppendTransformer(Transformer* transformer) +{ + if (!transformer) + return false; + + if (!fTransformers.AddItem((void*)transformer)) + return false; + + Notify(); + return true; +} diff --git a/src/apps/icon-o-matic/shape/Shape.h b/src/apps/icon-o-matic/shape/Shape.h index 63428550ff..b17a3a1193 100644 --- a/src/apps/icon-o-matic/shape/Shape.h +++ b/src/apps/icon-o-matic/shape/Shape.h @@ -1,10 +1,12 @@ #ifndef SHAPE_H #define SHAPE_H +#include #include #include "Observable.h" #include "PathContainer.h" +#include "PathSource.h" #include "Referenceable.h" class Style; @@ -32,9 +34,16 @@ class Shape : public Observable, BRect Bounds() const; + ::VertexSource& VertexSource(); + bool AppendTransformer( + Transformer* transformer); + private: PathContainer* fPaths; ::Style* fStyle; + + PathSource fPathSource; + BList fTransformers; }; #endif // SHAPE_H diff --git a/src/apps/icon-o-matic/transformer/PathSource.cpp b/src/apps/icon-o-matic/transformer/PathSource.cpp new file mode 100644 index 0000000000..15cc7a2e28 --- /dev/null +++ b/src/apps/icon-o-matic/transformer/PathSource.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "PathSource.h" + +#include "PathContainer.h" +#include "VectorPath.h" + +// constructor +PathSource::PathSource(PathContainer* paths) + : VertexSource(), + fPaths(paths), + fAGGPath(), + fAGGCurvedPath(fAGGPath) +{ +} + +// destructor +PathSource::~PathSource() +{ +} + +// rewind +void +PathSource::rewind(unsigned path_id) +{ + fAGGCurvedPath.rewind(path_id); +} + +// vertex +unsigned +PathSource::vertex(double* x, double* y) +{ + return fAGGCurvedPath.vertex(x, y); +} + +// Update +void +PathSource::Update() +{ + fAGGPath.remove_all(); + int32 count = fPaths->CountPaths(); + for (int32 i = 0; i < count; i++) { + VectorPath* path = fPaths->PathAtFast(i); + fAGGPath.start_new_path(); + path->GetAGGPathStorage(fAGGPath); + } +} + diff --git a/src/apps/icon-o-matic/transformer/PathSource.h b/src/apps/icon-o-matic/transformer/PathSource.h new file mode 100644 index 0000000000..3fe9156d56 --- /dev/null +++ b/src/apps/icon-o-matic/transformer/PathSource.h @@ -0,0 +1,39 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef PATH_SOURCE_H +#define PATH_SOURCE_H + +#include "Transformer.h" + +#include "agg_path_storage.h" +#include "agg_conv_curve.h" + +class PathContainer; +class VectorPath; + +typedef agg::path_storage AGGPath; +typedef agg::conv_curve AGGCurvedPath; + +class PathSource : public VertexSource { + public: + PathSource(PathContainer* paths); + virtual ~PathSource(); + + virtual void rewind(unsigned path_id); + virtual unsigned vertex(double* x, double* y); + + void Update(); + + private: + PathContainer* fPaths; + AGGPath fAGGPath; + AGGCurvedPath fAGGCurvedPath; +}; + +#endif // PATH_SOURCE_H diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp new file mode 100644 index 0000000000..a5205545b7 --- /dev/null +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "StrokeTransformer.h" + +// constructor +StrokeTransformer::StrokeTransformer(VertexSource& source) + : Transformer(source), + Stroke(source) +{ +} + +// destructor +StrokeTransformer::~StrokeTransformer() +{ +} + +// rewind +void +StrokeTransformer::rewind(unsigned path_id) +{ + Stroke::rewind(path_id); +} + +// vertex +unsigned +StrokeTransformer::vertex(double* x, double* y) +{ + return Stroke::vertex(x, y); +} + +// SetSource +void +StrokeTransformer::SetSource(VertexSource& source) +{ + Transformer::SetSource(source); + Stroke::attach(source); +} + diff --git a/src/apps/icon-o-matic/transformer/StrokeTransformer.h b/src/apps/icon-o-matic/transformer/StrokeTransformer.h new file mode 100644 index 0000000000..21f5fcf7d6 --- /dev/null +++ b/src/apps/icon-o-matic/transformer/StrokeTransformer.h @@ -0,0 +1,31 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef STROKE_TRANSFORMER_H +#define STROKE_TRANSFORMER_H + +#include "agg_conv_stroke.h" + +#include "Transformer.h" + +typedef agg::conv_stroke Stroke; + +class StrokeTransformer : public Transformer, + public Stroke { + public: + StrokeTransformer( + VertexSource& source); + virtual ~StrokeTransformer(); + + virtual void rewind(unsigned path_id); + virtual unsigned vertex(double* x, double* y); + + virtual void SetSource(VertexSource& source); +}; + +#endif // STROKE_TRANSFORMER_H diff --git a/src/apps/icon-o-matic/transformer/Transformer.cpp b/src/apps/icon-o-matic/transformer/Transformer.cpp new file mode 100644 index 0000000000..8829ef5ec9 --- /dev/null +++ b/src/apps/icon-o-matic/transformer/Transformer.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "Transformer.h" + +// constructor +VertexSource::VertexSource() +{ +} + +// destructor +VertexSource::~VertexSource() +{ +} + +// #pragma mark - + +// constructor +Transformer::Transformer(VertexSource& source) + : fSource(source) +{ +} + +// destructor +Transformer::~Transformer() +{ +} + +// rewind +void +Transformer::rewind(unsigned path_id) +{ + fSource.rewind(path_id); +} + +// vertex +unsigned +Transformer::vertex(double* x, double* y) +{ + return fSource.vertex(x, y); +} + +// SetSource +void +Transformer::SetSource(VertexSource& source) +{ + fSource = source; +} diff --git a/src/apps/icon-o-matic/transformer/Transformer.h b/src/apps/icon-o-matic/transformer/Transformer.h new file mode 100644 index 0000000000..b6b905481b --- /dev/null +++ b/src/apps/icon-o-matic/transformer/Transformer.h @@ -0,0 +1,36 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef TRANSFORMER_H +#define TRANSFORMER_H + +class VertexSource { + public: + VertexSource(); + virtual ~VertexSource(); + + virtual void rewind(unsigned path_id) = 0; + virtual unsigned vertex(double* x, double* y) = 0; +}; + + +class Transformer : public VertexSource { + public: + Transformer(VertexSource& source); + virtual ~Transformer(); + + virtual void rewind(unsigned path_id); + virtual unsigned vertex(double* x, double* y); + + virtual void SetSource(VertexSource& source); + + private: + VertexSource& fSource; +}; + +#endif // TRANSFORMER_H