Files
haiku-beta6/src/apps/icon-o-matic/shape/Shape.cpp
T
Stephan Aßmus 0199e126e2 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
2006-06-21 14:38:13 +00:00

127 lines
1.9 KiB
C++

#include "Shape.h"
#include <new>
#include <limits.h>
#include "Style.h"
#include "VectorPath.h"
using std::nothrow;
// constructor
Shape::Shape(::Style* style)
: Observable(),
Referenceable(),
PathContainerListener(),
fPaths(new (nothrow) PathContainer()),
fStyle(style),
fPathSource(fPaths),
fTransformers(4)
{
if (fPaths)
fPaths->AddListener(this);
if (fStyle)
fStyle->Acquire();
}
// 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;
if (fStyle)
fStyle->Release();
}
// PathAdded
void
Shape::PathAdded(VectorPath* path)
{
path->Acquire();
}
// PathRemoved
void
Shape::PathRemoved(VectorPath* path)
{
path->Release();
}
// #pragma mark -
// InitCheck
status_t
Shape::InitCheck() const
{
return fPaths ? B_OK : B_NO_MEMORY;
}
// SetStyle
void
Shape::SetStyle(::Style* style)
{
if (fStyle == style)
return;
if (fStyle)
fStyle->Release();
fStyle = style;
if (fStyle)
fStyle->Acquire();
Notify();
}
// Bounds
BRect
Shape::Bounds() const
{
BRect bounds(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
int32 count = fPaths->CountPaths();
for (int32 i = 0; i < count; i++)
bounds = bounds | fPaths->PathAtFast(i)->Bounds();
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;
}