* small cleanup in VectorPath

* cache the agg converted path in Shape on multiple
  calls to VertexSource (rendering multiple icons after
  a single change)
* added VertexSource::ApproximationScale() which is used
  to retrieve a suitable approximation scale for the
  whole Transformer pipeline
* added a couple more properties to Contour and Stroke


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18070 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-07-08 09:29:25 +00:00
parent 9b224ec82e
commit d4d2597fef
17 changed files with 183 additions and 43 deletions
@@ -66,6 +66,10 @@ name_for_id(int32 id)
name = "Scale Y";
break;
case PROPERTY_DETECT_ORIENTATION:
name = "Detect Orient.";
break;
default:
name = "<unkown property>";
break;
@@ -31,6 +31,8 @@ enum {
PROPERTY_ROTATION = 'rotn',
PROPERTY_SCALE_X = 'sclx',
PROPERTY_SCALE_Y = 'scly',
PROPERTY_DETECT_ORIENTATION = 'ador',
};
+26 -12
View File
@@ -33,6 +33,7 @@ Shape::Shape(::Style* style)
fPathSource(fPaths),
fTransformers(4),
fNeedsUpdate(true),
fLastBounds(0, 0, -1, -1)
{
@@ -53,6 +54,7 @@ Shape::Shape(const Shape& other)
fPathSource(fPaths),
fTransformers(4),
fNeedsUpdate(true),
fLastBounds(0, 0, -1, -1)
{
@@ -99,7 +101,7 @@ Shape::ObjectChanged(const Observable* object)
// simply pass on the event for now
// (a path, transformer or the style changed,
// the shape needs to be re-rendered)
Notify();
_NotifyRerender();
}
// #pragma mark -
@@ -110,7 +112,7 @@ Shape::PathAdded(VectorPath* path)
{
path->Acquire();
path->AddListener(this);
Notify();
_NotifyRerender();
}
// PathRemoved
@@ -118,7 +120,7 @@ void
Shape::PathRemoved(VectorPath* path)
{
path->RemoveListener(this);
Notify();
_NotifyRerender();
path->Release();
}
@@ -128,42 +130,42 @@ Shape::PathRemoved(VectorPath* path)
void
Shape::PointAdded(int32 index)
{
Notify();
_NotifyRerender();
}
// PointRemoved
void
Shape::PointRemoved(int32 index)
{
Notify();
_NotifyRerender();
}
// PointChanged
void
Shape::PointChanged(int32 index)
{
Notify();
_NotifyRerender();
}
// PathChanged
void
Shape::PathChanged()
{
Notify();
_NotifyRerender();
}
// PathClosedChanged
void
Shape::PathClosedChanged()
{
Notify();
_NotifyRerender();
}
// PathReversed
void
Shape::PathReversed()
{
Notify();
_NotifyRerender();
}
// #pragma mark -
@@ -194,7 +196,7 @@ Shape::SetStyle(::Style* style)
fStyle->AddObserver(this);
}
Notify();
_NotifyRerender();
}
// #pragma mark -
@@ -238,7 +240,11 @@ Shape::VertexSource()
source = t;
}
fPathSource.Update(source->WantsOpenPaths());
if (fNeedsUpdate) {
fPathSource.Update(source->WantsOpenPaths(),
source->ApproximationScale());
fNeedsUpdate = false;
}
return *source;
}
@@ -349,7 +355,7 @@ Shape::_NotifyTransformerAdded(Transformer* transformer, int32 index) const
listener->TransformerAdded(transformer, index);
}
// TODO: merge Observable and ShapeListener interface
Notify();
_NotifyRerender();
}
// _NotifyTransformerRemoved
@@ -364,5 +370,13 @@ Shape::_NotifyTransformerRemoved(Transformer* transformer) const
listener->TransformerRemoved(transformer);
}
// TODO: merge Observable and ShapeListener interface
_NotifyRerender();
}
// _NotifyRerender
void
Shape::_NotifyRerender() const
{
fNeedsUpdate = true;
Notify();
}
+3
View File
@@ -84,11 +84,14 @@ class Shape : public IconObject,
int32 index) const;
void _NotifyTransformerRemoved(Transformer* t) const;
void _NotifyRerender() const;
PathContainer* fPaths;
::Style* fStyle;
PathSource fPathSource;
BList fTransformers;
mutable bool fNeedsUpdate;
BList fListeners;
+28 -23
View File
@@ -95,6 +95,7 @@ VectorPath::VectorPath(const VectorPath& from)
IconObject(from),
fListeners(20),
fPath(NULL),
fClosed(false),
fPointCount(0),
fAllocCount(0),
fCachedBounds(0.0, 0.0, -1.0, -1.0)
@@ -113,31 +114,35 @@ VectorPath::VectorPath(const BMessage* archive)
fAllocCount(0),
fCachedBounds(0.0, 0.0, -1.0, -1.0)
{
if (archive) {
type_code typeFound;
int32 countFound;
if (archive->GetInfo("point", &typeFound, &countFound) >= B_OK
&& typeFound == B_POINT_TYPE && _SetPointCount(countFound)) {
memset(fPath, 0, fAllocCount * sizeof(control_point));
BPoint point;
BPoint pointIn;
BPoint pointOut;
bool connected;
for (int32 i = 0; i < fPointCount
&& archive->FindPoint("point", i, &point) >= B_OK
&& archive->FindPoint("point in", i, &pointIn) >= B_OK
&& archive->FindPoint("point out", i, &pointOut) >= B_OK
&& archive->FindBool("connected", i, &connected) >= B_OK; i++) {
fPath[i].point = point;
fPath[i].point_in = pointIn;
fPath[i].point_out = pointOut;
fPath[i].connected = connected;
}
}
if (archive->FindBool("path closed", &fClosed) < B_OK) {
fClosed = false;
if (!archive)
return;
type_code typeFound;
int32 countFound;
if (archive->GetInfo("point", &typeFound, &countFound) >= B_OK
&& typeFound == B_POINT_TYPE
&& _SetPointCount(countFound)) {
memset(fPath, 0, fAllocCount * sizeof(control_point));
BPoint point;
BPoint pointIn;
BPoint pointOut;
bool connected;
for (int32 i = 0; i < fPointCount
&& archive->FindPoint("point", i, &point) >= B_OK
&& archive->FindPoint("point in", i, &pointIn) >= B_OK
&& archive->FindPoint("point out", i, &pointOut) >= B_OK
&& archive->FindBool("connected", i, &connected) >= B_OK; i++) {
fPath[i].point = point;
fPath[i].point_in = pointIn;
fPath[i].point_out = pointOut;
fPath[i].connected = connected;
}
}
if (archive->FindBool("path closed", &fClosed) < B_OK)
fClosed = false;
}
// destructor
@@ -46,6 +46,13 @@ AffineTransformer::SetSource(VertexSource& source)
Affine::attach(source);
}
// ApproximationScale
double
AffineTransformer::ApproximationScale() const
{
return fSource.ApproximationScale() * scale();
}
// #pragma mark -
// MakePropertyObject
@@ -30,6 +30,8 @@ class AffineTransformer : public Transformer,
virtual void SetSource(VertexSource& source);
virtual double ApproximationScale() const;
// IconObject interface
virtual PropertyObject* MakePropertyObject() const;
virtual bool SetToPropertyObject(
@@ -9,6 +9,7 @@
#include "ContourTransformer.h"
#include "CommonPropertyIDs.h"
#include "OptionProperty.h"
#include "Property.h"
#include "PropertyObject.h"
@@ -17,6 +18,7 @@ ContourTransformer::ContourTransformer(VertexSource& source)
: Transformer(source, "Contour"),
Contour(source)
{
auto_detect_orientation(true);
}
// destructor
@@ -46,6 +48,13 @@ ContourTransformer::SetSource(VertexSource& source)
Contour::attach(source);
}
// ApproximationScale
double
ContourTransformer::ApproximationScale() const
{
return fSource.ApproximationScale() * width();
}
// #pragma mark -
// MakePropertyObject
@@ -59,6 +68,23 @@ ContourTransformer::MakePropertyObject() const
// width
object->AddProperty(new FloatProperty(PROPERTY_WIDTH, width()));
// auto detect orientation
object->AddProperty(new BoolProperty(PROPERTY_DETECT_ORIENTATION,
auto_detect_orientation()));
// join mode
OptionProperty* property = new OptionProperty(PROPERTY_JOIN_MODE);
property->AddOption(agg::miter_join, "Miter");
property->AddOption(agg::round_join, "Round");
property->AddOption(agg::bevel_join, "Bevel");
property->SetCurrentOptionID(line_join());
object->AddProperty(property);
// miter limit
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
miter_limit()));
return object;
}
@@ -76,6 +102,29 @@ ContourTransformer::SetToPropertyObject(const PropertyObject* object)
Notify();
}
// auto detect orientation
bool ado = object->Value(PROPERTY_DETECT_ORIENTATION,
auto_detect_orientation());
if (ado != auto_detect_orientation()) {
auto_detect_orientation(ado);
Notify();
}
// join mode
OptionProperty* property = dynamic_cast<OptionProperty*>(
object->FindProperty(PROPERTY_JOIN_MODE));
if (property && line_join() != property->CurrentOptionID()) {
line_join((agg::line_join_e)property->CurrentOptionID());
Notify();
}
// miter limit
float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit());
if (l != miter_limit()) {
miter_limit(l);
Notify();
}
return HasPendingNotifications();
}
@@ -27,6 +27,8 @@ class ContourTransformer : public Transformer,
virtual void SetSource(VertexSource& source);
virtual double ApproximationScale() const;
// IconObject interface
virtual PropertyObject* MakePropertyObject() const;
virtual bool SetToPropertyObject(
@@ -39,9 +39,25 @@ PathSource::vertex(double* x, double* y)
return fAGGCurvedPath.vertex(x, y);
}
// WantsOpenPaths
bool
PathSource::WantsOpenPaths() const
{
return false;
}
// ApproximationScale
double
PathSource::ApproximationScale() const
{
return 1.0;
}
// #pragma mark -
// Update
void
PathSource::Update(bool leavePathsOpen)
PathSource::Update(bool leavePathsOpen, double approximationScale)
{
fAGGPath.remove_all();
@@ -51,11 +67,7 @@ PathSource::Update(bool leavePathsOpen)
if (!leavePathsOpen)
fAGGPath.close_polygon();
}
fAGGCurvedPath.approximation_scale(approximationScale);
}
// WantsOpenPaths
bool
PathSource::WantsOpenPaths() const
{
return false;
}
@@ -29,9 +29,11 @@ class PathSource : public VertexSource {
virtual unsigned vertex(double* x, double* y);
virtual bool WantsOpenPaths() const;
virtual double ApproximationScale() const;
// PathSource
void Update(bool leavePathsOpen);
void Update(bool leavePathsOpen,
double approximationScale);
private:
PathContainer* fPaths;
@@ -42,6 +42,14 @@ PerspectiveTransformer::SetSource(VertexSource& source)
Perspective::attach(source);
}
// ApproximationScale
double
PerspectiveTransformer::ApproximationScale() const
{
// TODO: upgrade AGG
return fSource.ApproximationScale();// * scale();
}
@@ -29,6 +29,8 @@ class PerspectiveTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual double ApproximationScale() const;
};
#endif // PERSPECTIVE_TRANSFORMER_H
@@ -54,6 +54,13 @@ StrokeTransformer::WantsOpenPaths() const
return true;
}
// ApproximationScale
double
StrokeTransformer::ApproximationScale() const
{
return fSource.ApproximationScale() * width();
}
// #pragma mark -
// MakePropertyObject
@@ -85,6 +92,10 @@ StrokeTransformer::MakePropertyObject() const
object->AddProperty(property);
// miter limit
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
miter_limit()));
return object;
}
@@ -117,6 +128,12 @@ StrokeTransformer::SetToPropertyObject(const PropertyObject* object)
Notify();
}
// miter limit
float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit());
if (l != miter_limit()) {
miter_limit(l);
Notify();
}
return HasPendingNotifications();
}
@@ -26,7 +26,9 @@ class StrokeTransformer : public Transformer,
virtual unsigned vertex(double* x, double* y);
virtual void SetSource(VertexSource& source);
virtual bool WantsOpenPaths() const;
virtual double ApproximationScale() const;
// IconObject interface
virtual PropertyObject* MakePropertyObject() const;
@@ -60,3 +60,10 @@ Transformer::WantsOpenPaths() const
return fSource.WantsOpenPaths();
}
// ApproximationScale
double
Transformer::ApproximationScale() const
{
return fSource.ApproximationScale();
}
@@ -20,6 +20,7 @@ class VertexSource {
virtual unsigned vertex(double* x, double* y) = 0;
virtual bool WantsOpenPaths() const = 0;
virtual double ApproximationScale() const = 0;
};
@@ -36,6 +37,7 @@ class Transformer : public VertexSource,
virtual void SetSource(VertexSource& source);
virtual bool WantsOpenPaths() const;
virtual double ApproximationScale() const;
protected:
VertexSource& fSource;