1*c6c2c042SZardshard /*
2*c6c2c042SZardshard * Copyright 2006-2009, 2023, Haiku.
3*c6c2c042SZardshard * Distributed under the terms of the MIT License.
4*c6c2c042SZardshard *
5*c6c2c042SZardshard * Authors:
6*c6c2c042SZardshard * Stephan Aßmus <superstippi@gmx.de>
7*c6c2c042SZardshard * Zardshard
8*c6c2c042SZardshard */
9*c6c2c042SZardshard
10*c6c2c042SZardshard #include "PerspectiveBox.h"
11*c6c2c042SZardshard
12*c6c2c042SZardshard #include <stdio.h>
13*c6c2c042SZardshard
14*c6c2c042SZardshard #include <agg_trans_affine.h>
15*c6c2c042SZardshard #include <agg_math.h>
16*c6c2c042SZardshard
17*c6c2c042SZardshard #include <View.h>
18*c6c2c042SZardshard
19*c6c2c042SZardshard #include "CanvasView.h"
20*c6c2c042SZardshard #include "StateView.h"
21*c6c2c042SZardshard #include "support.h"
22*c6c2c042SZardshard #include "PerspectiveBoxStates.h"
23*c6c2c042SZardshard #include "PerspectiveCommand.h"
24*c6c2c042SZardshard #include "PerspectiveTransformer.h"
25*c6c2c042SZardshard
26*c6c2c042SZardshard
27*c6c2c042SZardshard #define INSET 8.0
28*c6c2c042SZardshard
29*c6c2c042SZardshard
30*c6c2c042SZardshard using std::nothrow;
31*c6c2c042SZardshard using namespace PerspectiveBoxStates;
32*c6c2c042SZardshard
33*c6c2c042SZardshard
PerspectiveBox(CanvasView * view,PerspectiveTransformer * parent)34*c6c2c042SZardshard PerspectiveBox::PerspectiveBox(CanvasView* view,
35*c6c2c042SZardshard PerspectiveTransformer* parent)
36*c6c2c042SZardshard :
37*c6c2c042SZardshard Manipulator(NULL),
38*c6c2c042SZardshard
39*c6c2c042SZardshard fLeftTop(parent->LeftTop()),
40*c6c2c042SZardshard fRightTop(parent->RightTop()),
41*c6c2c042SZardshard fLeftBottom(parent->LeftBottom()),
42*c6c2c042SZardshard fRightBottom(parent->RightBottom()),
43*c6c2c042SZardshard
44*c6c2c042SZardshard fCurrentCommand(NULL),
45*c6c2c042SZardshard fCurrentState(NULL),
46*c6c2c042SZardshard
47*c6c2c042SZardshard fDragging(false),
48*c6c2c042SZardshard fMousePos(-10000.0, -10000.0),
49*c6c2c042SZardshard fModifiers(0),
50*c6c2c042SZardshard
51*c6c2c042SZardshard fPreviousBox(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN),
52*c6c2c042SZardshard
53*c6c2c042SZardshard fCanvasView(view),
54*c6c2c042SZardshard fPerspective(parent),
55*c6c2c042SZardshard
56*c6c2c042SZardshard fDragLTState(new DragCornerState(this, &fLeftTop)),
57*c6c2c042SZardshard fDragRTState(new DragCornerState(this, &fRightTop)),
58*c6c2c042SZardshard fDragLBState(new DragCornerState(this, &fLeftBottom)),
59*c6c2c042SZardshard fDragRBState(new DragCornerState(this, &fRightBottom))
60*c6c2c042SZardshard {
61*c6c2c042SZardshard }
62*c6c2c042SZardshard
63*c6c2c042SZardshard
~PerspectiveBox()64*c6c2c042SZardshard PerspectiveBox::~PerspectiveBox()
65*c6c2c042SZardshard {
66*c6c2c042SZardshard _NotifyDeleted();
67*c6c2c042SZardshard
68*c6c2c042SZardshard delete fCurrentCommand;
69*c6c2c042SZardshard delete fDragLTState;
70*c6c2c042SZardshard delete fDragRTState;
71*c6c2c042SZardshard delete fDragLBState;
72*c6c2c042SZardshard delete fDragRBState;
73*c6c2c042SZardshard }
74*c6c2c042SZardshard
75*c6c2c042SZardshard
76*c6c2c042SZardshard void
Draw(BView * into,BRect updateRect)77*c6c2c042SZardshard PerspectiveBox::Draw(BView* into, BRect updateRect)
78*c6c2c042SZardshard {
79*c6c2c042SZardshard // convert to canvas view coordinates
80*c6c2c042SZardshard BPoint lt = fLeftTop;
81*c6c2c042SZardshard BPoint rt = fRightTop;
82*c6c2c042SZardshard BPoint lb = fLeftBottom;
83*c6c2c042SZardshard BPoint rb = fRightBottom;
84*c6c2c042SZardshard
85*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(<);
86*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&rt);
87*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&lb);
88*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&rb);
89*c6c2c042SZardshard
90*c6c2c042SZardshard into->SetDrawingMode(B_OP_COPY);
91*c6c2c042SZardshard into->SetHighColor(255, 255, 255, 255);
92*c6c2c042SZardshard into->SetLowColor(0, 0, 0, 255);
93*c6c2c042SZardshard
94*c6c2c042SZardshard _StrokeBWLine(into, lt, rt);
95*c6c2c042SZardshard _StrokeBWLine(into, rt, rb);
96*c6c2c042SZardshard _StrokeBWLine(into, rb, lb);
97*c6c2c042SZardshard _StrokeBWLine(into, lb, lt);
98*c6c2c042SZardshard
99*c6c2c042SZardshard _StrokeBWPoint(into, lt, 0.0);
100*c6c2c042SZardshard _StrokeBWPoint(into, rt, 90.0);
101*c6c2c042SZardshard _StrokeBWPoint(into, rb, 180.0);
102*c6c2c042SZardshard _StrokeBWPoint(into, lb, 270.0);
103*c6c2c042SZardshard }
104*c6c2c042SZardshard
105*c6c2c042SZardshard
106*c6c2c042SZardshard // #pragma mark -
107*c6c2c042SZardshard
108*c6c2c042SZardshard
109*c6c2c042SZardshard bool
MouseDown(BPoint where)110*c6c2c042SZardshard PerspectiveBox::MouseDown(BPoint where)
111*c6c2c042SZardshard {
112*c6c2c042SZardshard fCanvasView->FilterMouse(&where);
113*c6c2c042SZardshard fCanvasView->ConvertToCanvas(&where);
114*c6c2c042SZardshard
115*c6c2c042SZardshard fDragging = true;
116*c6c2c042SZardshard if (fCurrentState) {
117*c6c2c042SZardshard fCurrentState->SetOrigin(where);
118*c6c2c042SZardshard
119*c6c2c042SZardshard delete fCurrentCommand;
120*c6c2c042SZardshard fCurrentCommand = new (nothrow) PerspectiveCommand(this, fPerspective,
121*c6c2c042SZardshard fPerspective->LeftTop(), fPerspective->RightTop(),
122*c6c2c042SZardshard fPerspective->LeftBottom(), fPerspective->RightBottom());
123*c6c2c042SZardshard }
124*c6c2c042SZardshard
125*c6c2c042SZardshard return true;
126*c6c2c042SZardshard }
127*c6c2c042SZardshard
128*c6c2c042SZardshard
129*c6c2c042SZardshard void
MouseMoved(BPoint where)130*c6c2c042SZardshard PerspectiveBox::MouseMoved(BPoint where)
131*c6c2c042SZardshard {
132*c6c2c042SZardshard fCanvasView->FilterMouse(&where);
133*c6c2c042SZardshard fCanvasView->ConvertToCanvas(&where);
134*c6c2c042SZardshard
135*c6c2c042SZardshard if (fMousePos != where) {
136*c6c2c042SZardshard fMousePos = where;
137*c6c2c042SZardshard if (fCurrentState) {
138*c6c2c042SZardshard fCurrentState->DragTo(fMousePos, fModifiers);
139*c6c2c042SZardshard fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
140*c6c2c042SZardshard }
141*c6c2c042SZardshard }
142*c6c2c042SZardshard }
143*c6c2c042SZardshard
144*c6c2c042SZardshard
145*c6c2c042SZardshard Command*
MouseUp()146*c6c2c042SZardshard PerspectiveBox::MouseUp()
147*c6c2c042SZardshard {
148*c6c2c042SZardshard fDragging = false;
149*c6c2c042SZardshard return FinishTransaction();
150*c6c2c042SZardshard }
151*c6c2c042SZardshard
152*c6c2c042SZardshard
153*c6c2c042SZardshard bool
MouseOver(BPoint where)154*c6c2c042SZardshard PerspectiveBox::MouseOver(BPoint where)
155*c6c2c042SZardshard {
156*c6c2c042SZardshard fCanvasView->ConvertToCanvas(&where);
157*c6c2c042SZardshard
158*c6c2c042SZardshard fMousePos = where;
159*c6c2c042SZardshard fCurrentState = _DragStateFor(where, fCanvasView->ZoomLevel());
160*c6c2c042SZardshard
161*c6c2c042SZardshard if (fCurrentState) {
162*c6c2c042SZardshard fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
163*c6c2c042SZardshard return true;
164*c6c2c042SZardshard }
165*c6c2c042SZardshard
166*c6c2c042SZardshard return false;
167*c6c2c042SZardshard }
168*c6c2c042SZardshard
169*c6c2c042SZardshard
170*c6c2c042SZardshard // #pragma mark -
171*c6c2c042SZardshard
172*c6c2c042SZardshard
173*c6c2c042SZardshard BRect
Bounds()174*c6c2c042SZardshard PerspectiveBox::Bounds()
175*c6c2c042SZardshard {
176*c6c2c042SZardshard // convert from canvas view coordinates
177*c6c2c042SZardshard BPoint lt = fLeftTop;
178*c6c2c042SZardshard BPoint rt = fRightTop;
179*c6c2c042SZardshard BPoint lb = fLeftBottom;
180*c6c2c042SZardshard BPoint rb = fRightBottom;
181*c6c2c042SZardshard
182*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(<);
183*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&rt);
184*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&lb);
185*c6c2c042SZardshard fCanvasView->ConvertFromCanvas(&rb);
186*c6c2c042SZardshard
187*c6c2c042SZardshard BRect bounds;
188*c6c2c042SZardshard bounds.left = min4(lt.x, rt.x, lb.x, rb.x);
189*c6c2c042SZardshard bounds.top = min4(lt.y, rt.y, lb.y, rb.y);
190*c6c2c042SZardshard bounds.right = max4(lt.x, rt.x, lb.x, rb.x);
191*c6c2c042SZardshard bounds.bottom = max4(lt.y, rt.y, lb.y, rb.y);
192*c6c2c042SZardshard return bounds;
193*c6c2c042SZardshard }
194*c6c2c042SZardshard
195*c6c2c042SZardshard
196*c6c2c042SZardshard BRect
TrackingBounds(BView * withinView)197*c6c2c042SZardshard PerspectiveBox::TrackingBounds(BView* withinView)
198*c6c2c042SZardshard {
199*c6c2c042SZardshard return withinView->Bounds();
200*c6c2c042SZardshard }
201*c6c2c042SZardshard
202*c6c2c042SZardshard
203*c6c2c042SZardshard // #pragma mark -
204*c6c2c042SZardshard
205*c6c2c042SZardshard
206*c6c2c042SZardshard void
ModifiersChanged(uint32 modifiers)207*c6c2c042SZardshard PerspectiveBox::ModifiersChanged(uint32 modifiers)
208*c6c2c042SZardshard {
209*c6c2c042SZardshard fModifiers = modifiers;
210*c6c2c042SZardshard if (fDragging && fCurrentState) {
211*c6c2c042SZardshard fCurrentState->DragTo(fMousePos, fModifiers);
212*c6c2c042SZardshard }
213*c6c2c042SZardshard }
214*c6c2c042SZardshard
215*c6c2c042SZardshard
216*c6c2c042SZardshard bool
UpdateCursor()217*c6c2c042SZardshard PerspectiveBox::UpdateCursor()
218*c6c2c042SZardshard {
219*c6c2c042SZardshard if (fCurrentState) {
220*c6c2c042SZardshard fCurrentState->UpdateViewCursor(fCanvasView, fMousePos);
221*c6c2c042SZardshard return true;
222*c6c2c042SZardshard }
223*c6c2c042SZardshard return false;
224*c6c2c042SZardshard }
225*c6c2c042SZardshard
226*c6c2c042SZardshard
227*c6c2c042SZardshard // #pragma mark -
228*c6c2c042SZardshard
229*c6c2c042SZardshard
230*c6c2c042SZardshard void
AttachedToView(BView * view)231*c6c2c042SZardshard PerspectiveBox::AttachedToView(BView* view)
232*c6c2c042SZardshard {
233*c6c2c042SZardshard view->Invalidate(Bounds().InsetByCopy(-INSET, -INSET));
234*c6c2c042SZardshard }
235*c6c2c042SZardshard
236*c6c2c042SZardshard
237*c6c2c042SZardshard void
DetachedFromView(BView * view)238*c6c2c042SZardshard PerspectiveBox::DetachedFromView(BView* view)
239*c6c2c042SZardshard {
240*c6c2c042SZardshard view->Invalidate(Bounds().InsetByCopy(-INSET, -INSET));
241*c6c2c042SZardshard }
242*c6c2c042SZardshard
243*c6c2c042SZardshard
244*c6c2c042SZardshard // pragma mark -
245*c6c2c042SZardshard
246*c6c2c042SZardshard
247*c6c2c042SZardshard void
ObjectChanged(const Observable * object)248*c6c2c042SZardshard PerspectiveBox::ObjectChanged(const Observable* object)
249*c6c2c042SZardshard {
250*c6c2c042SZardshard }
251*c6c2c042SZardshard
252*c6c2c042SZardshard
253*c6c2c042SZardshard // pragma mark -
254*c6c2c042SZardshard
255*c6c2c042SZardshard
256*c6c2c042SZardshard void
TransformTo(BPoint leftTop,BPoint rightTop,BPoint leftBottom,BPoint rightBottom)257*c6c2c042SZardshard PerspectiveBox::TransformTo(
258*c6c2c042SZardshard BPoint leftTop, BPoint rightTop, BPoint leftBottom, BPoint rightBottom)
259*c6c2c042SZardshard {
260*c6c2c042SZardshard if (fLeftTop == leftTop
261*c6c2c042SZardshard && fRightTop == rightTop
262*c6c2c042SZardshard && fLeftBottom == leftBottom
263*c6c2c042SZardshard && fRightBottom == rightBottom)
264*c6c2c042SZardshard return;
265*c6c2c042SZardshard
266*c6c2c042SZardshard fLeftTop = leftTop;
267*c6c2c042SZardshard fRightTop = rightTop;
268*c6c2c042SZardshard fLeftBottom = leftBottom;
269*c6c2c042SZardshard fRightBottom = rightBottom;
270*c6c2c042SZardshard
271*c6c2c042SZardshard Update();
272*c6c2c042SZardshard }
273*c6c2c042SZardshard
274*c6c2c042SZardshard
275*c6c2c042SZardshard void
Update(bool deep)276*c6c2c042SZardshard PerspectiveBox::Update(bool deep)
277*c6c2c042SZardshard {
278*c6c2c042SZardshard BRect r = Bounds();
279*c6c2c042SZardshard BRect dirty(r | fPreviousBox);
280*c6c2c042SZardshard dirty.InsetBy(-INSET, -INSET);
281*c6c2c042SZardshard fCanvasView->Invalidate(dirty);
282*c6c2c042SZardshard fPreviousBox = r;
283*c6c2c042SZardshard
284*c6c2c042SZardshard if (deep)
285*c6c2c042SZardshard fPerspective->TransformTo(fLeftTop, fRightTop, fLeftBottom, fRightBottom);
286*c6c2c042SZardshard }
287*c6c2c042SZardshard
288*c6c2c042SZardshard
289*c6c2c042SZardshard Command*
FinishTransaction()290*c6c2c042SZardshard PerspectiveBox::FinishTransaction()
291*c6c2c042SZardshard {
292*c6c2c042SZardshard Command* command = fCurrentCommand;
293*c6c2c042SZardshard if (fCurrentCommand) {
294*c6c2c042SZardshard fCurrentCommand->SetNewPerspective(
295*c6c2c042SZardshard fPerspective->LeftTop(), fPerspective->RightTop(),
296*c6c2c042SZardshard fPerspective->LeftBottom(), fPerspective->RightBottom());
297*c6c2c042SZardshard fCurrentCommand = NULL;
298*c6c2c042SZardshard }
299*c6c2c042SZardshard return command;
300*c6c2c042SZardshard }
301*c6c2c042SZardshard
302*c6c2c042SZardshard
303*c6c2c042SZardshard // #pragma mark -
304*c6c2c042SZardshard
305*c6c2c042SZardshard
306*c6c2c042SZardshard bool
AddListener(PerspectiveBoxListener * listener)307*c6c2c042SZardshard PerspectiveBox::AddListener(PerspectiveBoxListener* listener)
308*c6c2c042SZardshard {
309*c6c2c042SZardshard if (listener && !fListeners.HasItem((void*)listener))
310*c6c2c042SZardshard return fListeners.AddItem((void*)listener);
311*c6c2c042SZardshard return false;
312*c6c2c042SZardshard }
313*c6c2c042SZardshard
314*c6c2c042SZardshard
315*c6c2c042SZardshard bool
RemoveListener(PerspectiveBoxListener * listener)316*c6c2c042SZardshard PerspectiveBox::RemoveListener(PerspectiveBoxListener* listener)
317*c6c2c042SZardshard {
318*c6c2c042SZardshard return fListeners.RemoveItem((void*)listener);
319*c6c2c042SZardshard }
320*c6c2c042SZardshard
321*c6c2c042SZardshard
322*c6c2c042SZardshard // #pragma mark -
323*c6c2c042SZardshard
324*c6c2c042SZardshard
325*c6c2c042SZardshard void
_NotifyDeleted() const326*c6c2c042SZardshard PerspectiveBox::_NotifyDeleted() const
327*c6c2c042SZardshard {
328*c6c2c042SZardshard BList listeners(fListeners);
329*c6c2c042SZardshard int32 count = listeners.CountItems();
330*c6c2c042SZardshard for (int32 i = 0; i < count; i++) {
331*c6c2c042SZardshard PerspectiveBoxListener* listener
332*c6c2c042SZardshard = (PerspectiveBoxListener*)listeners.ItemAtFast(i);
333*c6c2c042SZardshard listener->PerspectiveBoxDeleted(this);
334*c6c2c042SZardshard }
335*c6c2c042SZardshard }
336*c6c2c042SZardshard
337*c6c2c042SZardshard
338*c6c2c042SZardshard //! where is expected in canvas view coordinates
339*c6c2c042SZardshard DragState*
_DragStateFor(BPoint where,float canvasZoom)340*c6c2c042SZardshard PerspectiveBox::_DragStateFor(BPoint where, float canvasZoom)
341*c6c2c042SZardshard {
342*c6c2c042SZardshard DragState* state = NULL;
343*c6c2c042SZardshard
344*c6c2c042SZardshard // convert to canvas zoom level
345*c6c2c042SZardshard //
346*c6c2c042SZardshard // the conversion is necessary, because the "hot regions"
347*c6c2c042SZardshard // around a point should be the same size no matter what
348*c6c2c042SZardshard // zoom level the canvas is displayed at
349*c6c2c042SZardshard float inset = INSET / canvasZoom;
350*c6c2c042SZardshard
351*c6c2c042SZardshard // check if the cursor is over the corners
352*c6c2c042SZardshard float dLT = point_point_distance(fLeftTop, where);
353*c6c2c042SZardshard float dRT = point_point_distance(fRightTop, where);
354*c6c2c042SZardshard float dLB = point_point_distance(fLeftBottom, where);
355*c6c2c042SZardshard float dRB = point_point_distance(fRightBottom, where);
356*c6c2c042SZardshard float d = min4(dLT, dRT, dLB, dRB);
357*c6c2c042SZardshard if (d < inset) {
358*c6c2c042SZardshard if (d == dLT)
359*c6c2c042SZardshard state = fDragLTState;
360*c6c2c042SZardshard else if (d == dRT)
361*c6c2c042SZardshard state = fDragRTState;
362*c6c2c042SZardshard else if (d == dLB)
363*c6c2c042SZardshard state = fDragLBState;
364*c6c2c042SZardshard else if (d == dRB)
365*c6c2c042SZardshard state = fDragRBState;
366*c6c2c042SZardshard }
367*c6c2c042SZardshard
368*c6c2c042SZardshard return state;
369*c6c2c042SZardshard }
370*c6c2c042SZardshard
371*c6c2c042SZardshard
372*c6c2c042SZardshard void
_StrokeBWLine(BView * into,BPoint from,BPoint to) const373*c6c2c042SZardshard PerspectiveBox::_StrokeBWLine(BView* into, BPoint from, BPoint to) const
374*c6c2c042SZardshard {
375*c6c2c042SZardshard // find out how to offset the second line optimally
376*c6c2c042SZardshard BPoint offset(0.0, 0.0);
377*c6c2c042SZardshard // first, do we have a more horizontal line or a more vertical line?
378*c6c2c042SZardshard float xDiff = to.x - from.x;
379*c6c2c042SZardshard float yDiff = to.y - from.y;
380*c6c2c042SZardshard if (fabs(xDiff) > fabs(yDiff)) {
381*c6c2c042SZardshard // horizontal
382*c6c2c042SZardshard if (xDiff > 0.0) {
383*c6c2c042SZardshard offset.y = -1.0;
384*c6c2c042SZardshard } else {
385*c6c2c042SZardshard offset.y = 1.0;
386*c6c2c042SZardshard }
387*c6c2c042SZardshard } else {
388*c6c2c042SZardshard // vertical
389*c6c2c042SZardshard if (yDiff < 0.0) {
390*c6c2c042SZardshard offset.x = -1.0;
391*c6c2c042SZardshard } else {
392*c6c2c042SZardshard offset.x = 1.0;
393*c6c2c042SZardshard }
394*c6c2c042SZardshard }
395*c6c2c042SZardshard // stroke two lines in high and low color of the view
396*c6c2c042SZardshard into->StrokeLine(from, to, B_SOLID_LOW);
397*c6c2c042SZardshard from += offset;
398*c6c2c042SZardshard to += offset;
399*c6c2c042SZardshard into->StrokeLine(from, to, B_SOLID_HIGH);
400*c6c2c042SZardshard }
401*c6c2c042SZardshard
402*c6c2c042SZardshard
403*c6c2c042SZardshard void
_StrokeBWPoint(BView * into,BPoint point,double angle) const404*c6c2c042SZardshard PerspectiveBox::_StrokeBWPoint(BView* into, BPoint point, double angle) const
405*c6c2c042SZardshard {
406*c6c2c042SZardshard double x = point.x;
407*c6c2c042SZardshard double y = point.y;
408*c6c2c042SZardshard
409*c6c2c042SZardshard double x1 = x;
410*c6c2c042SZardshard double y1 = y - 5.0;
411*c6c2c042SZardshard
412*c6c2c042SZardshard double x2 = x - 5.0;
413*c6c2c042SZardshard double y2 = y - 5.0;
414*c6c2c042SZardshard
415*c6c2c042SZardshard double x3 = x - 5.0;
416*c6c2c042SZardshard double y3 = y;
417*c6c2c042SZardshard
418*c6c2c042SZardshard agg::trans_affine m;
419*c6c2c042SZardshard
420*c6c2c042SZardshard double xOffset = -x;
421*c6c2c042SZardshard double yOffset = -y;
422*c6c2c042SZardshard
423*c6c2c042SZardshard agg::trans_affine_rotation r(angle * M_PI / 180.0);
424*c6c2c042SZardshard
425*c6c2c042SZardshard r.transform(&xOffset, &yOffset);
426*c6c2c042SZardshard xOffset = x + xOffset;
427*c6c2c042SZardshard yOffset = y + yOffset;
428*c6c2c042SZardshard
429*c6c2c042SZardshard m.multiply(r);
430*c6c2c042SZardshard m.multiply(agg::trans_affine_translation(xOffset, yOffset));
431*c6c2c042SZardshard
432*c6c2c042SZardshard m.transform(&x, &y);
433*c6c2c042SZardshard m.transform(&x1, &y1);
434*c6c2c042SZardshard m.transform(&x2, &y2);
435*c6c2c042SZardshard m.transform(&x3, &y3);
436*c6c2c042SZardshard
437*c6c2c042SZardshard BPoint p[4];
438*c6c2c042SZardshard p[0] = BPoint(x, y);
439*c6c2c042SZardshard p[1] = BPoint(x1, y1);
440*c6c2c042SZardshard p[2] = BPoint(x2, y2);
441*c6c2c042SZardshard p[3] = BPoint(x3, y3);
442*c6c2c042SZardshard
443*c6c2c042SZardshard into->FillPolygon(p, 4, B_SOLID_HIGH);
444*c6c2c042SZardshard
445*c6c2c042SZardshard into->StrokeLine(p[0], p[1], B_SOLID_LOW);
446*c6c2c042SZardshard into->StrokeLine(p[1], p[2], B_SOLID_LOW);
447*c6c2c042SZardshard into->StrokeLine(p[2], p[3], B_SOLID_LOW);
448*c6c2c042SZardshard into->StrokeLine(p[3], p[0], B_SOLID_LOW);
449*c6c2c042SZardshard }
450