1/*
2 * Copyright 2006, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan Aßmus <superstippi@gmx.de>
7 */
8
9#include "TransformPointsCommand.h"
10
11#include <new>
12#include <stdio.h>
13
14#include "ChannelTransform.h"
15#include "VectorPath.h"
16
17using std::nothrow;
18
19// constructor
20TransformPointsCommand::TransformPointsCommand(
21								TransformBox* box,
22
23								VectorPath* path,
24								const int32* indices,
25								const control_point* points,
26								int32 count,
27
28								BPoint pivot,
29								BPoint translation,
30								double rotation,
31								double xScale,
32								double yScale,
33
34								const char* name,
35								int32 nameIndex)
36	: TransformCommand(pivot,
37					   translation,
38					   rotation,
39					   xScale,
40					   yScale,
41					   name,
42					   nameIndex),
43	  fTransformBox(box),
44	  fPath(path),
45	  fIndices(indices && count > 0 ?
46	  		   new (nothrow) int32[count] : NULL),
47	  fPoints(points && count > 0 ?
48	  			 new (nothrow) control_point[count] : NULL),
49	  fCount(count)
50{
51	if (!fIndices || !fPoints)
52		return;
53
54	memcpy(fIndices, indices, fCount * sizeof(int32));
55	memcpy(fPoints, points, fCount * sizeof(control_point));
56
57	if (fTransformBox)
58		fTransformBox->AddListener(this);
59}
60
61// destructor
62TransformPointsCommand::~TransformPointsCommand()
63{
64	if (fTransformBox)
65		fTransformBox->RemoveListener(this);
66
67	delete[] fIndices;
68	delete[] fPoints;
69}
70
71// InitCheck
72status_t
73TransformPointsCommand::InitCheck()
74{
75	return fPath && fIndices && fPoints ? TransformCommand::InitCheck()
76										: B_NO_INIT;
77}
78
79// #pragma mark -
80
81// TransformBoxDeleted
82void
83TransformPointsCommand::TransformBoxDeleted(
84									const TransformBox* box)
85{
86	if (fTransformBox == box) {
87		if (fTransformBox)
88			fTransformBox->RemoveListener(this);
89		fTransformBox = NULL;
90	}
91}
92
93// #pragma mark -
94
95// _SetTransformation
96status_t
97TransformPointsCommand::_SetTransformation(
98								BPoint pivot, BPoint translation,
99								double rotation,
100								double xScale, double yScale) const
101{
102	if (fTransformBox) {
103		fTransformBox->SetTransformation(pivot, translation,
104										 rotation, xScale, yScale);
105		return B_OK;
106	}
107
108
109	ChannelTransform transform;
110	transform.SetTransformation(pivot, translation,
111								rotation, xScale, yScale);
112	// restore original points and apply transformation
113	for (int32 i = 0; i < fCount; i++) {
114		BPoint point = transform.Transform(fPoints[i].point);
115		BPoint pointIn = transform.Transform(fPoints[i].point_in);
116		BPoint pointOut = transform.Transform(fPoints[i].point_out);
117		if (!fPath->SetPoint(fIndices[i], point, pointIn, pointOut,
118							 fPoints[i].connected))
119			return B_ERROR;
120	}
121
122	return B_OK;
123}
124
125