1e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford/*
2e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Copyright (C) 2012 The Android Open Source Project
3e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
4e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
5e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * you may not use this file except in compliance with the License.
6e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * You may obtain a copy of the License at
7e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
8e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
9e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
10e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Unless required by applicable law or agreed to in writing, software
11e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
12e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * See the License for the specific language governing permissions and
14e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * limitations under the License.
15e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford */
16e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
17e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordpackage com.android.gallery3d.filtershow.imageshow;
18e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
19e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.content.Context;
20e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.content.res.Resources;
21e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Canvas;
22e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Color;
23e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.DashPathEffect;
24e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Matrix;
25e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Paint;
26e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.RadialGradient;
27e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Rect;
28e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport android.graphics.Shader;
29e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
30e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordimport com.android.gallery3d.R;
31e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
32e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordpublic class GradControl {
33e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mPoint1X = Float.NaN; // used to flag parameters have not been set
34e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mPoint1Y = 0;
35e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mPoint2X = 200;
36e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mPoint2Y = 300;
37e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int mMinTouchDist = 80;// should be a resource & in dips
38e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
39e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float[] handlex = new float[3];
40e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float[] handley = new float[3];
41e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int mSliderColor;
42e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int mCenterDotSize;
43e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownX;
44e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownY;
45e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownPoint1X;
46e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownPoint1Y;
47e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownPoint2X;
48e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float mDownPoint2Y;
49e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    Rect mImageBounds;
50e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    int mImageHeight;
51e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private Matrix mScrToImg;
52e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    Paint mPaint = new Paint();
53e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    DashPathEffect mDash = new DashPathEffect(new float[]{30, 30}, 0);
54e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private boolean mShowReshapeHandles = true;
55e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public final static int HAN_CENTER = 0;
56e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public final static int HAN_NORTH = 2;
57e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public final static int HAN_SOUTH = 1;
58e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int[] mPointColorPatern;
59e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int[] mGrayPointColorPatern;
60e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private float[] mPointRadialPos = new float[]{0, .3f, .31f, 1};
61e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int mLineColor;
62e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private int mlineShadowColor;
63e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
64e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public GradControl(Context context) {
65e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
66e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        Resources res = context.getResources();
67e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mCenterDotSize = (int) res.getDimension(R.dimen.gradcontrol_dot_size);
68e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mMinTouchDist = (int) res.getDimension(R.dimen.gradcontrol_min_touch_dist);
69e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int grayPointCenterColor = res.getColor(R.color.gradcontrol_graypoint_center);
70e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int grayPointEdgeColor = res.getColor(R.color.gradcontrol_graypoint_edge);
71e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int pointCenterColor = res.getColor(R.color.gradcontrol_point_center);
72e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int pointEdgeColor = res.getColor(R.color.gradcontrol_point_edge);
73e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int pointShadowStartColor = res.getColor(R.color.gradcontrol_point_shadow_start);
74e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int pointShadowEndColor = res.getColor(R.color.gradcontrol_point_shadow_end);
75e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPointColorPatern = new int[]{
76e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                pointCenterColor, pointEdgeColor, pointShadowStartColor, pointShadowEndColor};
77e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mGrayPointColorPatern = new int[]{
78e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                grayPointCenterColor, grayPointEdgeColor, pointShadowStartColor, pointShadowEndColor};
79e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mSliderColor = Color.WHITE;
80e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mLineColor = res.getColor(R.color.gradcontrol_line_color);
81e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mlineShadowColor = res.getColor(R.color.gradcontrol_line_shadow);
82e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
83e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
84e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void setPoint2(float x, float y) {
85e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPoint2X = x;
86e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPoint2Y = y;
87e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
88e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
89e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void setPoint1(float x, float y) {
90e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPoint1X = x;
91e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPoint1Y = y;
92e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
93e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
94e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public int getCloseHandle(float x, float y) {
95e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float min = Float.MAX_VALUE;
96e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int handle = -1;
97e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        for (int i = 0; i < handlex.length; i++) {
98e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            float dx = handlex[i] - x;
99e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            float dy = handley[i] - y;
100e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            float dist = dx * dx + dy * dy;
101e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            if (dist < min) {
102e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                min = dist;
103e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                handle = i;
104e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            }
105e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
106e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
107e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        if (min < mMinTouchDist * mMinTouchDist) {
108e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            return handle;
109e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
110e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        for (int i = 0; i < handlex.length; i++) {
111e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            float dx = handlex[i] - x;
112e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            float dy = handley[i] - y;
1138a55d3ae7486b798e4c26eeb91993916145f3cefNeil Fuller            float dist = (float) Math.hypot(dx, dy);
114e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
115e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
116e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        return -1;
117e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
118e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
119e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void setScrImageInfo(Matrix scrToImg, Rect imageBounds) {
120e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mScrToImg = scrToImg;
121e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mImageBounds = new Rect(imageBounds);
122e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
123e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
124e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    private boolean centerIsOutside(float x1, float y1, float x2, float y2) {
125e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        return (!mImageBounds.contains((int) ((x1 + x2) / 2), (int) ((y1 + y2) / 2)));
126e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
127e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
128e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void actionDown(float x, float y, Line line) {
129e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float[] point = new float[]{
130e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                x, y};
131e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mScrToImg.mapPoints(point);
132e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownX = point[0];
133e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownY = point[1];
134e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownPoint1X = line.getPoint1X();
135e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownPoint1Y = line.getPoint1Y();
136e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownPoint2X = line.getPoint2X();
137e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mDownPoint2Y = line.getPoint2Y();
138e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
139e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
140e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void actionMove(int handle, float x, float y, Line line) {
141e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float[] point = new float[]{
142e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                x, y};
143e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mScrToImg.mapPoints(point);
144e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        x = point[0];
145e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        y = point[1];
146e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
147e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        // Test if the matrix is swapping x and y
148e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        point[0] = 0;
149e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        point[1] = 1;
150e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mScrToImg.mapVectors(point);
151e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        boolean swapxy = (point[0] > 0.0f);
152e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
153e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        int sign = 1;
154e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
155e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float dx = x - mDownX;
156e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float dy = y - mDownY;
157e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        switch (handle) {
158e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            case HAN_CENTER:
159e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy,
160e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                        mDownPoint2X + dx, mDownPoint2Y + dy)) {
161e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                    break;
162e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                }
163e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy);
164e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy);
165e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                break;
166e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            case HAN_SOUTH:
167e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy,
168e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                        mDownPoint2X, mDownPoint2Y)) {
169e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                    break;
170e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                }
171e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy);
172e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                break;
173e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            case HAN_NORTH:
174e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                if (centerIsOutside(mDownPoint1X, mDownPoint1Y,
175e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                        mDownPoint2X + dx, mDownPoint2Y + dy)) {
176e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                    break;
177e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                }
178e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy);
179e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                break;
180e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
181e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
182e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
183e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void paintGrayPoint(Canvas canvas, float x, float y) {
184e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        if (isUndefined()) {
185e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            return;
186e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
187e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
188e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        Paint paint = new Paint();
189e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paint.setStyle(Paint.Style.FILL);
190e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mGrayPointColorPatern,
191e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                mPointRadialPos, Shader.TileMode.CLAMP);
192e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paint.setShader(g);
193e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        canvas.drawCircle(x, y, mCenterDotSize, paint);
194e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
195e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
196e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void paintPoint(Canvas canvas, float x, float y) {
197e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        if (isUndefined()) {
198e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            return;
199e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
200e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
201e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        Paint paint = new Paint();
202e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paint.setStyle(Paint.Style.FILL);
203e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mPointColorPatern,
204e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford                mPointRadialPos, Shader.TileMode.CLAMP);
205e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paint.setShader(g);
206e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        canvas.drawCircle(x, y, mCenterDotSize, paint);
207e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
208e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
209e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    void paintLines(Canvas canvas, float p1x, float p1y, float p2x, float p2y) {
210e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        if (isUndefined()) {
211e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            return;
212e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        }
213e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
214e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setAntiAlias(true);
215e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setStyle(Paint.Style.STROKE);
216e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
217e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setStrokeWidth(6);
218e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setColor(mlineShadowColor);
219e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setPathEffect(mDash);
220e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y);
221e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
222e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setStrokeWidth(3);
223e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setColor(mLineColor);
224e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        mPaint.setPathEffect(mDash);
225e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y);
226e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
227e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
228e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void paintOvallines(
229e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            Canvas canvas, Paint paint, float p1x, float p1y, float p2x, float p2y) {
230e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
231e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
232e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
233e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        canvas.drawLine(p1x, p1y, p2x, p2y, paint);
234e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
235e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float cx = (p1x + p2x) / 2;
236e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float cy = (p1y + p2y) / 2;
237e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float dx = p1x - p2x;
238e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float dy = p1y - p2y;
2398a55d3ae7486b798e4c26eeb91993916145f3cefNeil Fuller        float len = (float) Math.hypot(dx, dy);
240e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        dx *= 2048 / len;
241e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        dy *= 2048 / len;
242e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
243e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        canvas.drawLine(p1x + dy, p1y - dx, p1x - dy, p1y + dx, paint);
244e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        canvas.drawLine(p2x + dy, p2y - dx, p2x - dy, p2y + dx, paint);
245e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
246e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
247e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void fillHandles(Canvas canvas, float p1x, float p1y, float p2x, float p2y) {
248e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float cx = (p1x + p2x) / 2;
249e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float cy = (p1y + p2y) / 2;
250e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handlex[0] = cx;
251e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handley[0] = cy;
252e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handlex[1] = p1x;
253e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handley[1] = p1y;
254e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handlex[2] = p2x;
255e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        handley[2] = p2y;
256e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
257e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
258e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
259e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void draw(Canvas canvas) {
260e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintLines(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
261e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        fillHandles(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
262e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintPoint(canvas, mPoint2X, mPoint2Y);
263e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintPoint(canvas, mPoint1X, mPoint1Y);
264e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        paintPoint(canvas, (mPoint1X + mPoint2X) / 2, (mPoint1Y + mPoint2Y) / 2);
265e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
266e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
267e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public boolean isUndefined() {
268e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        return Float.isNaN(mPoint1X);
269e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
270e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
271e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    public void setShowReshapeHandles(boolean showReshapeHandles) {
272e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        this.mShowReshapeHandles = showReshapeHandles;
273e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
274e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford}
275