Path_Delegate.java revision 9a4fe29c8d92014d2d9a848e9116b8cc9d0842f9
1d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet/*
2d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project
3d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
4d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
5d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * you may not use this file except in compliance with the License.
6d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * You may obtain a copy of the License at
7d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
8d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
9d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
10d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * Unless required by applicable law or agreed to in writing, software
11d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
12d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * See the License for the specific language governing permissions and
14d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * limitations under the License.
15d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet */
16d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
17d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetpackage android.graphics;
18d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
19918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog;
20d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport com.android.layoutlib.bridge.Bridge;
21d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport com.android.layoutlib.bridge.impl.DelegateManager;
229a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohetimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
23d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
24d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport android.graphics.Path.Direction;
25d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport android.graphics.Path.FillType;
26d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
27d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.Shape;
28d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.AffineTransform;
29d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.Arc2D;
30d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.Area;
31d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.GeneralPath;
32d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.PathIterator;
33d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.Point2D;
34d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetimport java.awt.geom.Rectangle2D;
35d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
36d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet/**
37d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * Delegate implementing the native methods of android.graphics.Path
38d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
39d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * Through the layoutlib_create tool, the original native methods of Path have been replaced
40d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * by calls to methods of the same name in this delegate class.
41d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
42d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * This class behaves like the original native implementation, but in Java, keeping previously
43d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * native data into its own objects and mapping them to int that are sent back and forth between
44d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * it and the original Path class.
45d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
46d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet * @see DelegateManager
47d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet *
48d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet */
49d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetpublic final class Path_Delegate {
50d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
51d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    // ---- delegate manager ----
52d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private static final DelegateManager<Path_Delegate> sManager =
53d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            new DelegateManager<Path_Delegate>();
54d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
55d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    // ---- delegate data ----
56d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private FillType mFillType = FillType.WINDING;
57d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private GeneralPath mPath = new GeneralPath();
58d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
59d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private float mLastX = 0;
60d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private float mLastY = 0;
61d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
62d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    // ---- Public Helper methods ----
63d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
64d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    public static Path_Delegate getDelegate(int nPath) {
65d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return sManager.getDelegate(nPath);
66d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
67d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
68d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    public Shape getJavaShape() {
69d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return mPath;
70d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
71d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
72b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    public void setJavaShape(Shape shape) {
73b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet        mPath.reset();
74b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet        mPath.append(shape, false /*connect*/);
75b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    }
76b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet
77b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    public void reset() {
78b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet        mPath.reset();
79b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    }
80b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet
81b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    public void setPathIterator(PathIterator iterator) {
82b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet        mPath.reset();
83b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet        mPath.append(iterator, false /*connect*/);
84b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet    }
85b44b43b1579486ff7ecd0f7528f17711acdeae98Xavier Ducrohet
86d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    // ---- native methods ----
87d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
889a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
89d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static int init1() {
90d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // create the delegate
91d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate newDelegate = new Path_Delegate();
92d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
93d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return sManager.addDelegate(newDelegate);
94d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
95d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
969a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
97d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static int init2(int nPath) {
98d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // create the delegate
99d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate newDelegate = new Path_Delegate();
100d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
101d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        // get the delegate to copy, which could be null if nPath is 0
102d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
103d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        if (pathDelegate != null) {
104d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            newDelegate.set(pathDelegate);
105d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
106d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
107d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return sManager.addDelegate(newDelegate);
108d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
109d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1109a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
111d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_reset(int nPath) {
112d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
113d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
114d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
115d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
116d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
117d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.mPath.reset();
118d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
119d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1209a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
121d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_rewind(int nPath) {
122d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // call out to reset since there's nothing to optimize in
123d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // terms of data structs.
124d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        native_reset(nPath);
125d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
126d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1279a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
128d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_set(int native_dst, int native_src) {
129d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
130d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDstDelegate == null) {
131d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
132d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
133d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
134d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
135d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathSrcDelegate == null) {
136d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
137d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
138d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
139d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDstDelegate.set(pathSrcDelegate);
140d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
141d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1429a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
143d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static int native_getFillType(int nPath) {
144d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
145d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
146d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return 0;
147d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
148d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
149d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return pathDelegate.mFillType.nativeInt;
150d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
151d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1529a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
153d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_setFillType(int nPath, int ft) {
154d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
155d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
156d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
157d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
158d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
159d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.mFillType = Path.sFillTypeArray[ft];
160d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
161d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1629a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
163d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static boolean native_isEmpty(int nPath) {
164d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
165d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
166d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return true;
167d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
168d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
169d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return pathDelegate.isEmpty();
170d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
171d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1729a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
173d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static boolean native_isRect(int nPath, RectF rect) {
174d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
175d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
176d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return false;
177d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
178d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
179d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // create an Area that can test if the path is a rect
180d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Area area = new Area(pathDelegate.mPath);
181d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (area.isRectangular()) {
182d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            if (rect != null) {
183d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                pathDelegate.fillBounds(rect);
184d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            }
185d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
186d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return true;
187d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
188d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
189d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return false;
190d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
191d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
1929a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
193d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_computeBounds(int nPath, RectF bounds) {
194d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
195d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
196d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
197d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
198d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
199d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.fillBounds(bounds);
200d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
201d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2029a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
203d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_incReserve(int nPath, int extraPtCount) {
204d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // since we use a java2D path, there's no way to pre-allocate new points,
205d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // so we do nothing.
206d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
207d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2089a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
209d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_moveTo(int nPath, float x, float y) {
210d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
211d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
212d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
213d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
214d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
215d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.moveTo(x, y);
216d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
217d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2189a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
219d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_rMoveTo(int nPath, float dx, float dy) {
220d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
221d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
222d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
223d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
224d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
225d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.rMoveTo(dx, dy);
226d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
227d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2289a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
229d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_lineTo(int nPath, float x, float y) {
230d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
231d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
232d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
233d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
234d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
235d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.lineTo(x, y);
236d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
237d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2389a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
239d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_rLineTo(int nPath, float dx, float dy) {
240d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
241d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
242d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
243d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
244d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
245d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.rLineTo(dx, dy);
246d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
247d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2489a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
249d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_quadTo(int nPath, float x1, float y1, float x2, float y2) {
250d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
251d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
252d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
253d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
254d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
255d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.quadTo(x1, y1, x2, y2);
256d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
257d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2589a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
259b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_rQuadTo(int nPath, float dx1, float dy1, float dx2, float dy2) {
260d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
261d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
262d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
263d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
264d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
265d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
266d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
267d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2689a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
269d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_cubicTo(int nPath, float x1, float y1,
270b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet            float x2, float y2, float x3, float y3) {
271d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
272d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
273d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
274d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
275d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
276d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
277d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
278d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2799a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
280d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_rCubicTo(int nPath, float x1, float y1,
281b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet            float x2, float y2, float x3, float y3) {
282d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
283d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
284d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
285d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
286d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
287d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
288d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
289d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
2909a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
291d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_arcTo(int nPath, RectF oval,
292d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                    float startAngle, float sweepAngle, boolean forceMoveTo) {
293d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
294d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
295d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
296d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
297d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
298d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
299d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
300d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3019a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
302d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_close(int nPath) {
303d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
304d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
305d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
306d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
307d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
308d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.close();
309d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
310d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3119a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
312d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addRect(int nPath, RectF rect, int dir) {
313d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
314d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
315d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
316d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
317d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
318d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
319d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
320d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3219a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
322b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_addRect(int nPath,
323b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet            float left, float top, float right, float bottom, int dir) {
324d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
325d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
326d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
327d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
328d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
329d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.addRect(left, top, right, bottom, dir);
330d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
331d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3329a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
333d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
334d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
335d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
336d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
337d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3389a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
339b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_addCircle(int nPath, float x, float y, float radius, int dir) {
340d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
341d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
342d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
343d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3449a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
345d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addArc(int nPath, RectF oval,
346b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet            float startAngle, float sweepAngle) {
347d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
348d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
349d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
350d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3519a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
352d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addRoundRect(int nPath, RectF rect,
353b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet            float rx, float ry, int dir) {
354d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
355d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
356d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
357d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3589a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
359b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_addRoundRect(int nPath, RectF r, float[] radii, int dir) {
360d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
361d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
362d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
363d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3649a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
365b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_addPath(int nPath, int src, float dx, float dy) {
366d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
367d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
368d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
369d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3709a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
371d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addPath(int nPath, int src) {
372b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet        native_addPath(nPath, src, 0, 0);
373d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
374d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3759a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
376d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_addPath(int nPath, int src, int matrix) {
377d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        // FIXME
378d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new UnsupportedOperationException();
379d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
380d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3819a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
382b6e53f481294aec2edac5d83d9fde81827c23bd7Xavier Ducrohet    /*package*/ static void native_offset(int nPath, float dx, float dy, int dst_path) {
383d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
384d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
385d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
386d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
387d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
388d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        // could be null if the int is 0;
389d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
390d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
391d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.offset(dx, dy, dstDelegate);
392d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
393d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3949a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
395d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_offset(int nPath, float dx, float dy) {
396d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        native_offset(nPath, dx, dy, 0);
397d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
398d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
3999a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
400d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_setLastPoint(int nPath, float dx, float dy) {
401d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
402d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
403d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
404d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
405d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
406d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.mLastX = dx;
407d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.mLastY = dy;
408d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
409d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
4109a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
411d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_transform(int nPath, int matrix,
412d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                                                int dst_path) {
413d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
414d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (pathDelegate == null) {
415d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
416d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
417d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
418d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
419d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (matrixDelegate == null) {
420d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            return;
421d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
422d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
423d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        // this can be null if dst_path is 0
424d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
425d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
426d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        pathDelegate.transform(matrixDelegate, dstDelegate);
427d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
428d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
4299a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
430d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void native_transform(int nPath, int matrix) {
431d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        native_transform(nPath, matrix, 0);
432d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
433d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
4349a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
435d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /*package*/ static void finalizer(int nPath) {
436d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        sManager.removeDelegate(nPath);
437d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
438d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
439d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
440d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    // ---- Private helper methods ----
441d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
442d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void set(Path_Delegate delegate) {
443d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.reset();
444d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        setFillType(delegate.mFillType);
445d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.append(delegate.mPath, false /*connect*/);
446d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
447d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
448d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void setFillType(FillType fillType) {
449d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mFillType = fillType;
450d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.setWindingRule(getWindingRule(fillType));
451d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
452d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
453d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
454d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Returns the Java2D winding rules matching a given Android {@link FillType}.
455d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param type the android fill type
456d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @return the matching java2d winding rule.
457d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
458d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private static int getWindingRule(FillType type) {
459d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        switch (type) {
460d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case WINDING:
461d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case INVERSE_WINDING:
462d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                return GeneralPath.WIND_NON_ZERO;
463d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case EVEN_ODD:
464d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case INVERSE_EVEN_ODD:
465d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                return GeneralPath.WIND_EVEN_ODD;
466d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
467d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
468d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        assert false;
469d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        throw new IllegalArgumentException();
470d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
471d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
472d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private static Direction getDirection(int direction) {
473d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        for (Direction d : Direction.values()) {
474d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            if (direction == d.nativeInt) {
475d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                return d;
476d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            }
477d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
478d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
479d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        assert false;
480d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return null;
481d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
482d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
483d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
484d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Returns whether the path is empty.
485d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @return true if the path is empty.
486d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
487d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private boolean isEmpty() {
488d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        return mPath.getCurrentPoint() == null;
489d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
490d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
491d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
492d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Fills the given {@link RectF} with the path bounds.
493d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param bounds the RectF to be filled.
494d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
495d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void fillBounds(RectF bounds) {
496d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Rectangle2D rect = mPath.getBounds2D();
497d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        bounds.left = (float)rect.getMinX();
498d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        bounds.right = (float)rect.getMaxX();
499d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        bounds.top = (float)rect.getMinY();
500d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        bounds.bottom = (float)rect.getMaxY();
501d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
502d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
503d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
504d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Set the beginning of the next contour to the point (x,y).
505d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
506d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x The x-coordinate of the start of a new contour
507d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y The y-coordinate of the start of a new contour
508d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
509d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void moveTo(float x, float y) {
510d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.moveTo(mLastX = x, mLastY = y);
511d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
512d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
513d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
514d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Set the beginning of the next contour relative to the last point on the
515d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * previous contour. If there is no previous contour, this is treated the
516d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * same as moveTo().
517d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
518d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dx The amount to add to the x-coordinate of the end of the
519d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *           previous contour, to specify the start of a new contour
520d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dy The amount to add to the y-coordinate of the end of the
521d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *           previous contour, to specify the start of a new contour
522d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
523d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void rMoveTo(float dx, float dy) {
524d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx += mLastX;
525d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy += mLastY;
526d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.moveTo(mLastX = dx, mLastY = dy);
527d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
528d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
529d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
530d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Add a line from the last point to the specified point (x,y).
531d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * If no moveTo() call has been made for this contour, the first point is
532d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * automatically set to (0,0).
533d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
534d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x The x-coordinate of the end of a line
535d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y The y-coordinate of the end of a line
536d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
537d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void lineTo(float x, float y) {
538d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.lineTo(mLastX = x, mLastY = y);
539d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
540d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
541d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
542d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Same as lineTo, but the coordinates are considered relative to the last
543d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * point on this contour. If there is no previous point, then a moveTo(0,0)
544d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * is inserted automatically.
545d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
546d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dx The amount to add to the x-coordinate of the previous point on
547d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *           this contour, to specify a line
548d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dy The amount to add to the y-coordinate of the previous point on
549d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *           this contour, to specify a line
550d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
551d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void rLineTo(float dx, float dy) {
552d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (isEmpty()) {
553d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            mPath.moveTo(mLastX = 0, mLastY = 0);
554d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
555d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx += mLastX;
556d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy += mLastY;
557d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.lineTo(mLastX = dx, mLastY = dy);
558d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
559d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
560d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
561d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Add a quadratic bezier from the last point, approaching control point
562d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
563d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * this contour, the first point is automatically set to (0,0).
564d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
565d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x1 The x-coordinate of the control point on a quadratic curve
566d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y1 The y-coordinate of the control point on a quadratic curve
567d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x2 The x-coordinate of the end point on a quadratic curve
568d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y2 The y-coordinate of the end point on a quadratic curve
569d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
570d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void quadTo(float x1, float y1, float x2, float y2) {
571d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
572d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
573d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
574d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
575d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Same as quadTo, but the coordinates are considered relative to the last
576d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * point on this contour. If there is no previous point, then a moveTo(0,0)
577d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * is inserted automatically.
578d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
579d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dx1 The amount to add to the x-coordinate of the last point on
580d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *            this contour, for the control point of a quadratic curve
581d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dy1 The amount to add to the y-coordinate of the last point on
582d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *            this contour, for the control point of a quadratic curve
583d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dx2 The amount to add to the x-coordinate of the last point on
584d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *            this contour, for the end point of a quadratic curve
585d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dy2 The amount to add to the y-coordinate of the last point on
586d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *            this contour, for the end point of a quadratic curve
587d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
588d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
589d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (isEmpty()) {
590d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            mPath.moveTo(mLastX = 0, mLastY = 0);
591d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
592d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx1 += mLastX;
593d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy1 += mLastY;
594d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx2 += mLastX;
595d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy2 += mLastY;
596d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
597d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
598d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
599d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
600d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Add a cubic bezier from the last point, approaching control points
601d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
602d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * made for this contour, the first point is automatically set to (0,0).
603d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
604d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x1 The x-coordinate of the 1st control point on a cubic curve
605d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y1 The y-coordinate of the 1st control point on a cubic curve
606d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
607d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
608d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param x3 The x-coordinate of the end point on a cubic curve
609d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param y3 The y-coordinate of the end point on a cubic curve
610d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
611d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void cubicTo(float x1, float y1, float x2, float y2,
612d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                        float x3, float y3) {
613d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
614d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
615d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
616d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
617d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Same as cubicTo, but the coordinates are considered relative to the
618d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * current point on this contour. If there is no previous point, then a
619d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * moveTo(0,0) is inserted automatically.
620d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
621d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
622d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                         float dx3, float dy3) {
623d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (isEmpty()) {
624d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            mPath.moveTo(mLastX = 0, mLastY = 0);
625d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
626d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx1 += mLastX;
627d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy1 += mLastY;
628d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx2 += mLastX;
629d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy2 += mLastY;
630d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dx3 += mLastX;
631d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        dy3 += mLastY;
632d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
633d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
634d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
635d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
636d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Append the specified arc to the path as a new contour. If the start of
637d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * the path is different from the path's current last point, then an
638d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * automatic lineTo() is added to connect the current contour to the
639d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * start of the arc. However, if the path is empty, then we call moveTo()
640d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * with the first point of the arc. The sweep angle is tread mod 360.
641d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
642d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param oval        The bounds of oval defining shape and size of the arc
643d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param startAngle  Starting angle (in degrees) where the arc begins
644d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
645d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *                    mod 360.
646d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param forceMoveTo If true, always begin a new contour with the arc
647d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
648d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void arcTo(RectF oval, float startAngle, float sweepAngle,
649d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                      boolean forceMoveTo) {
650d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Arc2D arc = new Arc2D.Float(oval.left, oval.top, oval.width(), oval.height(), startAngle,
651d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                sweepAngle, Arc2D.OPEN);
652d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.append(arc, true /*connect*/);
653d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
654d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        resetLastPointFromPath();
655d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
656d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
657d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
658d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Close the current contour. If the current point is not equal to the
659d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * first point of the contour, a line segment is automatically added.
660d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
661d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void close() {
662d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mPath.closePath();
663d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
664d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
665d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void resetLastPointFromPath() {
666d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Point2D last = mPath.getCurrentPoint();
667d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mLastX = (float) last.getX();
668d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        mLastY = (float) last.getY();
669d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
670d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
671d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
672d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Add a closed rectangle contour to the path
673d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
674d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param left   The left side of a rectangle to add to the path
675d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param top    The top of a rectangle to add to the path
676d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param right  The right side of a rectangle to add to the path
677d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param bottom The bottom of a rectangle to add to the path
678d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dir    The direction to wind the rectangle's contour
679d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
680d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    private void addRect(float left, float top, float right, float bottom,
681d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                        int dir) {
682d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        moveTo(left, top);
683d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
684d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        Direction direction = getDirection(dir);
685d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
686d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        switch (direction) {
687d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case CW:
688d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(right, top);
689d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(right, bottom);
690d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(left, bottom);
691d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                break;
692d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            case CCW:
693d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(left, bottom);
694d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(right, bottom);
695d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                lineTo(right, top);
696d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                break;
697d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
698d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
699d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        close();
700d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
701d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        resetLastPointFromPath();
702d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
703d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
704d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
705d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Offset the path by (dx,dy), returning true on success
706d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
707d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dx  The amount in the X direction to offset the entire path
708d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dy  The amount in the Y direction to offset the entire path
709d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dst The translated path is written here. If this is null, then
710d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *            the original path is modified.
711d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
712d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    public void offset(float dx, float dy, Path_Delegate dst) {
713d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        GeneralPath newPath = new GeneralPath();
714d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
715d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
716d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
717d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        newPath.append(iterator, false /*connect*/);
718d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
719d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (dst != null) {
720d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            dst.mPath = newPath;
721d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        } else {
722d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            mPath = newPath;
723d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
724d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
725d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
726d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    /**
727d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * Transform the points in this path by matrix, and write the answer
728d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * into dst. If dst is null, then the the original path is modified.
729d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *
730d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param matrix The matrix to apply to the path
731d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     * @param dst    The transformed path is written here. If dst is null,
732d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     *               then the the original path is modified
733d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet     */
734d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
735d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (matrix.hasPerspective()) {
736d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            assert false;
737918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
738d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet                    "android.graphics.Path#transform() only " +
73951a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                    "supports affine transformations.", null, null /*data*/);
740d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
741d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
742d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        GeneralPath newPath = new GeneralPath();
743d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
744d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
745d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
746d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        newPath.append(iterator, false /*connect*/);
747d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet
748d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        if (dst != null) {
749d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            dst.mPath = newPath;
750d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        } else {
751d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet            mPath = newPath;
752d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet        }
753d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet    }
754d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohet}
755