#include "StrokeTransformer.h"
#ifdef ICON_O_MATIC
# include <Message.h>
# include "CommonPropertyIDs.h"
# include "OptionProperty.h"
# include "Property.h"
# include "PropertyObject.h"
#endif
#include <new>
_USING_ICON_NAMESPACE
using std::nothrow;
StrokeTransformer::StrokeTransformer(VertexSource& source)
: Transformer("Stroke"),
PathTransformer(source),
Stroke(source)
{
}
StrokeTransformer::StrokeTransformer(VertexSource& source,
BMessage* archive)
: Transformer(archive),
PathTransformer(source),
Stroke(source)
{
if (!archive)
return;
int32 mode;
if (archive->FindInt32("line cap", &mode) == B_OK)
line_cap((agg::line_cap_e)mode);
if (archive->FindInt32("line join", &mode) == B_OK)
line_join((agg::line_join_e)mode);
if (archive->FindInt32("inner join", &mode) == B_OK)
inner_join((agg::inner_join_e)mode);
double value;
if (archive->FindDouble("width", &value) == B_OK)
width(value);
if (archive->FindDouble("miter limit", &value) == B_OK)
miter_limit(value);
if (archive->FindDouble("inner miter limit", &value) == B_OK)
inner_miter_limit(value);
if (archive->FindDouble("shorten", &value) == B_OK)
shorten(value);
}
StrokeTransformer::~StrokeTransformer()
{
}
Transformer*
StrokeTransformer::Clone() const
{
StrokeTransformer* clone = new (nothrow) StrokeTransformer(*fSource);
if (clone) {
clone->line_cap(line_cap());
clone->line_join(line_join());
clone->inner_join(inner_join());
clone->width(width());
clone->miter_limit(miter_limit());
clone->inner_miter_limit(inner_miter_limit());
clone->shorten(shorten());
}
return clone;
}
void
StrokeTransformer::rewind(unsigned path_id)
{
Stroke::rewind(path_id);
}
unsigned
StrokeTransformer::vertex(double* x, double* y)
{
return Stroke::vertex(x, y);
}
void
StrokeTransformer::SetSource(VertexSource& source)
{
PathTransformer::SetSource(source);
Stroke::attach(source);
}
bool
StrokeTransformer::WantsOpenPaths() const
{
return true;
}
double
StrokeTransformer::ApproximationScale() const
{
double scale = fSource->ApproximationScale();
double factor = fabs(width());
if (factor > 1.0)
scale *= factor;
return scale;
}
#ifdef ICON_O_MATIC
status_t
StrokeTransformer::Archive(BMessage* into, bool deep) const
{
status_t ret = Transformer::Archive(into, deep);
if (ret == B_OK)
into->what = archive_code;
if (ret == B_OK)
ret = into->AddInt32("line cap", line_cap());
if (ret == B_OK)
ret = into->AddInt32("line join", line_join());
if (ret == B_OK)
ret = into->AddInt32("inner join", inner_join());
if (ret == B_OK)
ret = into->AddDouble("width", width());
if (ret == B_OK)
ret = into->AddDouble("miter limit", miter_limit());
if (ret == B_OK)
ret = into->AddDouble("inner miter limit", inner_miter_limit());
if (ret == B_OK)
ret = into->AddDouble("shorten",shorten());
return ret;
}
PropertyObject*
StrokeTransformer::MakePropertyObject() const
{
PropertyObject* object = Transformer::MakePropertyObject();
if (!object)
return NULL;
object->AddProperty(new FloatProperty(PROPERTY_WIDTH, width()));
OptionProperty* property = new OptionProperty(PROPERTY_CAP_MODE);
property->AddOption(agg::butt_cap, "Butt");
property->AddOption(agg::square_cap, "Square");
property->AddOption(agg::round_cap, "Round");
property->SetCurrentOptionID(line_cap());
object->AddProperty(property);
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);
if (line_join() == agg::miter_join) {
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
miter_limit()));
}
return object;
}
bool
StrokeTransformer::SetToPropertyObject(const PropertyObject* object)
{
AutoNotificationSuspender _(this);
Transformer::SetToPropertyObject(object);
float w = object->Value(PROPERTY_WIDTH, (float)width());
if (w != width()) {
width(w);
Notify();
}
OptionProperty* property = dynamic_cast<OptionProperty*>(
object->FindProperty(PROPERTY_CAP_MODE));
if (property && line_cap() != property->CurrentOptionID()) {
line_cap((agg::line_cap_e)property->CurrentOptionID());
Notify();
}
property = dynamic_cast<OptionProperty*>(
object->FindProperty(PROPERTY_JOIN_MODE));
if (property && line_join() != property->CurrentOptionID()) {
line_join((agg::line_join_e)property->CurrentOptionID());
Notify();
}
float l = object->Value(PROPERTY_MITER_LIMIT, (float)miter_limit());
if (l != miter_limit()) {
miter_limit(l);
Notify();
}
float s = object->Value(PROPERTY_STROKE_SHORTEN, (float)shorten());
if (s != shorten()) {
shorten(s);
Notify();
}
return HasPendingNotifications();
}
#endif