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<agg::path_storage> 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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
// ----
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include <Bitmap.h>
|
||||
|
||||
#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<agg::path_storage> curve(aggPath);
|
||||
fRasterizer.add_path(curve);
|
||||
|
||||
fRasterizer.add_path(shape->VertexSource());
|
||||
}
|
||||
|
||||
StyleHandler styleHandler(fStyles, fGammaTable);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#ifndef SHAPE_H
|
||||
#define SHAPE_H
|
||||
|
||||
#include <List.h>
|
||||
#include <Rect.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#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<AGGPath> 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
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef STROKE_TRANSFORMER_H
|
||||
#define STROKE_TRANSFORMER_H
|
||||
|
||||
#include "agg_conv_stroke.h"
|
||||
|
||||
#include "Transformer.h"
|
||||
|
||||
typedef agg::conv_stroke<VertexSource> 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
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*/
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user