1738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang/*
2738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * Copyright (C) 2010 The Android Open Source Project
3738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang *
4738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * Licensed under the Apache License, Version 2.0 (the "License");
5738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * you may not use this file except in compliance with the License.
6738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * You may obtain a copy of the License at
7738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang *
8738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang *      http://www.apache.org/licenses/LICENSE-2.0
9738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang *
10738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * Unless required by applicable law or agreed to in writing, software
11738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * distributed under the License is distributed on an "AS IS" BASIS,
12738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * See the License for the specific language governing permissions and
14738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * limitations under the License.
15738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang */
16738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
17738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangpackage com.android.gallery3d.photoeditor.actions;
18738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
19738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.Color;
20738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.Matrix;
21738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.Paint;
22738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.Path;
23738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.PointF;
24738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.graphics.RectF;
25738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.os.Parcel;
26738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport android.os.Parcelable;
27738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
28738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangimport java.util.Vector;
29738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
30738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang/**
31738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang * Doodle that consists of a color and doodling path for drawing.
32738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang */
33738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huangpublic class Doodle implements Parcelable {
34738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
35738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    private final int color;
36738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    private final Path normalizedPath = new Path();
37738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    private final Vector<PointF> points = new Vector<PointF>();
38738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
39738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    /**
40738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     * Creates paint for doodles.
41738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     */
42738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public static Paint createPaint() {
43738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        Paint paint = new Paint(Paint.DITHER_FLAG | Paint.ANTI_ALIAS_FLAG);
44738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        paint.setStyle(Paint.Style.STROKE);
45738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        paint.setStrokeJoin(Paint.Join.ROUND);
46738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        paint.setStrokeCap(Paint.Cap.ROUND);
47738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        paint.setStrokeWidth(15);
48738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        return paint;
49738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
50738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
51738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public Doodle(int color, PointF startPoint) {
52738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        this.color = Color.argb(192, Color.red(color), Color.green(color), Color.blue(color));
53738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        normalizedPath.moveTo(startPoint.x, startPoint.y);
54738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        points.add(startPoint);
55738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
56738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
57738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    /**
58738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     * Adds control points whose coordinates range from 0 to 1 to construct the doodle path.
59738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     *
60738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     * @return true if the constructed path is in (0, 0, 1, 1) bounds; otherwise, false.
61738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     */
62738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public boolean addControlPoint(PointF point) {
63738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        PointF last = points.lastElement();
64738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        normalizedPath.quadTo(last.x, last.y, (last.x + point.x) / 2, (last.y + point.y) / 2);
65738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        points.add(point);
66738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
67738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        RectF r = new RectF();
68738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        normalizedPath.computeBounds(r, false);
69738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        return r.intersects(0, 0, 1, 1);
70738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
71738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
72738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public int getColor() {
73738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        return color;
74738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
75738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
76738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public boolean isEmpty() {
77738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        return normalizedPath.isEmpty();
78738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
79738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
80738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    /**
81738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     * Gets the drawing path from the normalized doodle path.
82738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang     */
83738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public void getDrawingPath(Matrix matrix, Path path) {
84738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        path.set(normalizedPath);
85738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        path.transform(matrix);
86738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
87738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
88738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    @Override
89738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public int describeContents() {
90738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        return 0;
91738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
92738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
93738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    @Override
94738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public void writeToParcel(Parcel dest, int flags) {
95738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        dest.writeInt(color);
96738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        dest.writeInt(points.size());
97738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        for (PointF point : points) {
98738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            dest.writeParcelable(point, 0);
99738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        }
100738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    }
101738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
102738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang    public static final Parcelable.Creator<Doodle> CREATOR = new Parcelable.Creator<Doodle>() {
103738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
104738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        @Override
105738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        public Doodle createFromParcel(Parcel source) {
106738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            int color = source.readInt();
107738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            int size = source.readInt();
108738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            if (size > 0) {
109738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang                Doodle doodle = new Doodle(color, (PointF) source.readParcelable(null));
110738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang                for (int i = 1; i < size; i++) {
111738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang                    doodle.addControlPoint((PointF) source.readParcelable(null));
112738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang                }
113738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang                return doodle;
114738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            }
115738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            return new Doodle(color, new PointF(0, 0));
116738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        }
117738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang
118738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        @Override
119738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        public Doodle[] newArray(int size) {
120738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang            return new Doodle[size];
121738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang        }};
122738e82e163f90e1fe7aeef8bd153dc7763631f30Yuli Huang}
123