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:
Stephan Aßmus
2006-06-21 14:38:13 +00:00
parent 954f408f50
commit 0199e126e2
11 changed files with 348 additions and 35 deletions
+10 -5
View File
@@ -20,6 +20,7 @@ local sourceDirs =
shape
shape/commands
style
transformer
;
local sourceDir ;
@@ -56,9 +57,8 @@ Application Icon-O-Matic :
# generic/support
RWLocker.cpp
support.cpp
#style
Style.cpp
StyleManager.cpp
# gradient
Gradient.cpp
# shape
PathContainer.cpp
PathManipulator.cpp
@@ -71,8 +71,13 @@ Application Icon-O-Matic :
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
+19 -5
View File
@@ -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);
+38 -1
View File
@@ -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;
}
+9
View File
@@ -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