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	: TransformCommand(pivot,
36					   translation,
37					   rotation,
38					   xScale,
39					   yScale,
40					   name),
41	  fTransformBox(box),
42	  fPath(path),
43	  fIndices(indices && count > 0 ?
44	  		   new (nothrow) int32[count] : NULL),
45	  fPoints(points && count > 0 ?
46	  			 new (nothrow) control_point[count] : NULL),
47	  fCount(count)
48{
49	if (!fIndices || !fPoints)
50		return;
51
52	memcpy(fIndices, indices, fCount * sizeof(int32));
53	memcpy((void*)fPoints, points, fCount * sizeof(control_point));
54
55	if (fTransformBox)
56		fTransformBox->AddListener(this);
57}
58
59// destructor
60TransformPointsCommand::~TransformPointsCommand()
61{
62	if (fTransformBox)
63		fTransformBox->RemoveListener(this);
64
65	delete[] fIndices;
66	delete[] fPoints;
67}
68
69// InitCheck
70status_t
71TransformPointsCommand::InitCheck()
72{
73	return fPath && fIndices && fPoints ? TransformCommand::InitCheck()
74										: B_NO_INIT;
75}
76
77// #pragma mark -
78
79// TransformBoxDeleted
80void
81TransformPointsCommand::TransformBoxDeleted(
82									const TransformBox* box)
83{
84	if (fTransformBox == box) {
85		if (fTransformBox)
86			fTransformBox->RemoveListener(this);
87		fTransformBox = NULL;
88	}
89}
90
91// #pragma mark -
92
93// _SetTransformation
94status_t
95TransformPointsCommand::_SetTransformation(
96								BPoint pivot, BPoint translation,
97								double rotation,
98								double xScale, double yScale) const
99{
100	if (fTransformBox) {
101		fTransformBox->SetTransformation(pivot, translation,
102										 rotation, xScale, yScale);
103		return B_OK;
104	}
105
106
107	ChannelTransform transform;
108	transform.SetTransformation(pivot, translation,
109								rotation, xScale, yScale);
110	// restore original points and apply transformation
111	for (int32 i = 0; i < fCount; i++) {
112		BPoint point = transform.Transform(fPoints[i].point);
113		BPoint pointIn = transform.Transform(fPoints[i].point_in);
114		BPoint pointOut = transform.Transform(fPoints[i].point_out);
115		if (!fPath->SetPoint(fIndices[i], point, pointIn, pointOut,
116							 fPoints[i].connected))
117			return B_ERROR;
118	}
119
120	return B_OK;
121}
122
123