blob: 33296e1abdc99ad98a8b14f637e63b850dc8ce78 [file] [log] [blame]
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -080019import com.android.ide.common.rendering.api.LayoutLog;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -080020import com.android.layoutlib.bridge.Bridge;
Xavier Ducrohet3bd98982010-11-09 18:25:03 -080021import com.android.layoutlib.bridge.impl.DelegateManager;
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -080022import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070023
Deepanshu Gupta442aee62015-05-22 14:11:22 -070024import android.annotation.NonNull;
25import android.annotation.Nullable;
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -070026import android.graphics.FontFamily_Delegate.FontVariant;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070027import android.graphics.Paint.FontMetrics;
28import android.graphics.Paint.FontMetricsInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070029import android.text.TextUtils;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070030
Xavier Ducrohet37f21802010-11-01 16:17:18 -070031import java.awt.BasicStroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070032import java.awt.Font;
Xavier Ducrohetb9761242010-12-23 10:22:14 -080033import java.awt.Shape;
34import java.awt.Stroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070035import java.awt.Toolkit;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070036import java.awt.geom.AffineTransform;
37import java.util.ArrayList;
38import java.util.Collections;
39import java.util.List;
Xavier Ducrohet43526ab2012-04-23 17:41:37 -070040import java.util.Locale;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070041
Deepanshu Guptafbe158f2015-10-06 17:56:37 -070042import libcore.util.NativeAllocationRegistry_Delegate;
43
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070044/**
45 * Delegate implementing the native methods of android.graphics.Paint
46 *
47 * Through the layoutlib_create tool, the original native methods of Paint have been replaced
48 * by calls to methods of the same name in this delegate class.
49 *
50 * This class behaves like the original native implementation, but in Java, keeping previously
51 * native data into its own objects and mapping them to int that are sent back and forth between
52 * it and the original Paint class.
53 *
54 * @see DelegateManager
55 *
56 */
57public class Paint_Delegate {
58
59 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -070060 * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070061 */
Xavier Ducrohet37f21802010-11-01 16:17:18 -070062 /*package*/ static final class FontInfo {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070063 Font mFont;
64 java.awt.FontMetrics mMetrics;
65 }
66
67 // ---- delegate manager ----
68 private static final DelegateManager<Paint_Delegate> sManager =
Xavier Ducrohetb2de8392011-02-23 16:51:08 -080069 new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
Deepanshu Guptafbe158f2015-10-06 17:56:37 -070070 private static long sFinalizer = -1;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070071
72 // ---- delegate helper data ----
Deepanshu Gupta382256f2014-08-09 14:14:32 -070073
74 // This list can contain null elements.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070075 private List<FontInfo> mFonts;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070076
77 // ---- delegate data ----
78 private int mFlags;
79 private int mColor;
80 private int mStyle;
81 private int mCap;
82 private int mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070083 private int mTextAlign;
Xavier Ducrohet91672792011-02-22 11:54:37 -080084 private Typeface_Delegate mTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070085 private float mStrokeWidth;
86 private float mStrokeMiter;
87 private float mTextSize;
88 private float mTextScaleX;
89 private float mTextSkewX;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -070090 private int mHintingMode = Paint.HINTING_ON;
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -070091 private int mHyphenEdit;
92 private float mLetterSpacing; // not used in actual text rendering.
Deepanshu Gupta8916b212014-06-11 15:40:47 -070093 // Variant of the font. A paint's variant can only be compact or elegant.
94 private FontVariant mFontVariant = FontVariant.COMPACT;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070095
Xavier Ducrohet91672792011-02-22 11:54:37 -080096 private Xfermode_Delegate mXfermode;
97 private ColorFilter_Delegate mColorFilter;
98 private Shader_Delegate mShader;
99 private PathEffect_Delegate mPathEffect;
100 private MaskFilter_Delegate mMaskFilter;
101 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -0700102
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700103 private Locale mLocale = Locale.getDefault();
104
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700105 // Used only to assert invariants.
106 public long mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700107
108 // ---- Public Helper methods ----
109
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -0700110 @Nullable
Narayan Kamath633d6882014-01-27 14:24:16 +0000111 public static Paint_Delegate getDelegate(long native_paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700112 return sManager.getDelegate(native_paint);
113 }
114
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700115 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700116 * Returns the list of {@link Font} objects.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700117 */
118 public List<FontInfo> getFonts() {
119 return mFonts;
120 }
121
Xavier Ducroheta313b652010-11-01 18:45:20 -0700122 public boolean isAntiAliased() {
123 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
124 }
125
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700126 public boolean isFilterBitmap() {
127 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
128 }
129
130 public int getStyle() {
131 return mStyle;
132 }
133
134 public int getColor() {
135 return mColor;
136 }
137
Xavier Ducrohet66225222010-12-21 01:33:04 -0800138 public int getAlpha() {
139 return mColor >>> 24;
140 }
141
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800142 public void setAlpha(int alpha) {
143 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
144 }
145
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700146 public int getTextAlign() {
147 return mTextAlign;
148 }
149
150 public float getStrokeWidth() {
151 return mStrokeWidth;
152 }
153
Xavier Ducrohet66225222010-12-21 01:33:04 -0800154 /**
155 * returns the value of stroke miter needed by the java api.
156 */
157 public float getJavaStrokeMiter() {
Diego Pereza1c60152015-12-18 16:01:24 +0000158 return mStrokeMiter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700159 }
160
161 public int getJavaCap() {
162 switch (Paint.sCapArray[mCap]) {
163 case BUTT:
164 return BasicStroke.CAP_BUTT;
165 case ROUND:
166 return BasicStroke.CAP_ROUND;
167 default:
168 case SQUARE:
169 return BasicStroke.CAP_SQUARE;
170 }
171 }
172
173 public int getJavaJoin() {
174 switch (Paint.sJoinArray[mJoin]) {
175 default:
176 case MITER:
177 return BasicStroke.JOIN_MITER;
178 case ROUND:
179 return BasicStroke.JOIN_ROUND;
180 case BEVEL:
181 return BasicStroke.JOIN_BEVEL;
182 }
183 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700184
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800185 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800186 if (mPathEffect != null) {
187 if (mPathEffect.isSupported()) {
188 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800189 assert stroke != null;
190 if (stroke != null) {
191 return stroke;
192 }
193 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800194 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800195 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800196 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800197 }
198 }
199
200 // if no custom stroke as been set, set the default one.
201 return new BasicStroke(
202 getStrokeWidth(),
203 getJavaCap(),
204 getJavaJoin(),
205 getJavaStrokeMiter());
206 }
207
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800208 /**
209 * Returns the {@link Xfermode} delegate or null if none have been set
210 *
211 * @return the delegate or null.
212 */
213 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800214 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700215 }
216
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800217 /**
218 * Returns the {@link ColorFilter} delegate or null if none have been set
219 *
220 * @return the delegate or null.
221 */
222 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800223 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700224 }
225
Diego Pereze4cf18f2016-02-23 12:19:11 +0000226 public void setColorFilter(long colorFilterPtr) {
227 mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
228 }
229
Diego Perez741ef6a2016-03-01 16:20:43 +0000230 public void setShader(long shaderPtr) {
231 mShader = Shader_Delegate.getDelegate(shaderPtr);
232 }
233
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800234 /**
235 * Returns the {@link Shader} delegate or null if none have been set
236 *
237 * @return the delegate or null.
238 */
239 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800240 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700241 }
242
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800243 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800244 * Returns the {@link MaskFilter} delegate or null if none have been set
245 *
246 * @return the delegate or null.
247 */
248 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800249 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800250 }
251
252 /**
253 * Returns the {@link Rasterizer} delegate or null if none have been set
254 *
255 * @return the delegate or null.
256 */
257 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800258 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700259 }
260
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700261 // ---- native methods ----
262
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800263 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700264 /*package*/ static int nGetFlags(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700265 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700266 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700267 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700268 return 0;
269 }
270
271 return delegate.mFlags;
272 }
273
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700274
275
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800276 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700277 /*package*/ static void nSetFlags(Paint thisPaint, long nativePaint, int flags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700278 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700279 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700280 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700281 return;
282 }
283
284 delegate.mFlags = flags;
285 }
286
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800287 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700288 /*package*/ static void nSetFilterBitmap(Paint thisPaint, long nativePaint, boolean filter) {
289 setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700290 }
291
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800292 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700293 /*package*/ static int nGetHinting(Paint thisPaint, long nativePaint) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700294 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700295 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700296 if (delegate == null) {
297 return Paint.HINTING_ON;
298 }
299
300 return delegate.mHintingMode;
301 }
302
303 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700304 /*package*/ static void nSetHinting(Paint thisPaint, long nativePaint, int mode) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700305 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700306 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700307 if (delegate == null) {
308 return;
309 }
310
311 delegate.mHintingMode = mode;
312 }
313
314 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700315 /*package*/ static void nSetAntiAlias(Paint thisPaint, long nativePaint, boolean aa) {
316 setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700317 }
318
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800319 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700320 /*package*/ static void nSetSubpixelText(Paint thisPaint, long nativePaint,
321 boolean subpixelText) {
322 setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700323 }
324
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800325 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700326 /*package*/ static void nSetUnderlineText(Paint thisPaint, long nativePaint,
327 boolean underlineText) {
328 setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700329 }
330
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800331 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700332 /*package*/ static void nSetStrikeThruText(Paint thisPaint, long nativePaint,
333 boolean strikeThruText) {
334 setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700335 }
336
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800337 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700338 /*package*/ static void nSetFakeBoldText(Paint thisPaint, long nativePaint,
339 boolean fakeBoldText) {
340 setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700341 }
342
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800343 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700344 /*package*/ static void nSetDither(Paint thisPaint, long nativePaint, boolean dither) {
345 setFlag(nativePaint, Paint.DITHER_FLAG, dither);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700346 }
347
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800348 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700349 /*package*/ static void nSetLinearText(Paint thisPaint, long nativePaint, boolean linearText) {
350 setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700351 }
352
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800353 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700354 /*package*/ static int nGetColor(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700355 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700356 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700357 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700358 return 0;
359 }
360
361 return delegate.mColor;
362 }
363
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800364 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700365 /*package*/ static void nSetColor(Paint thisPaint, long nativePaint, int color) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700366 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700367 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700368 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700369 return;
370 }
371
372 delegate.mColor = color;
373 }
374
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800375 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700376 /*package*/ static int nGetAlpha(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700377 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700378 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700379 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 return 0;
381 }
382
Xavier Ducrohet66225222010-12-21 01:33:04 -0800383 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700384 }
385
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800386 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700387 /*package*/ static void nSetAlpha(Paint thisPaint, long nativePaint, int a) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700388 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700389 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700390 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700391 return;
392 }
393
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800394 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700395 }
396
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800397 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700398 /*package*/ static float nGetStrokeWidth(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700399 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700400 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700401 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700402 return 1.f;
403 }
404
405 return delegate.mStrokeWidth;
406 }
407
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800408 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700409 /*package*/ static void nSetStrokeWidth(Paint thisPaint, long nativePaint, float width) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700410 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700411 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700412 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700413 return;
414 }
415
416 delegate.mStrokeWidth = width;
417 }
418
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800419 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700420 /*package*/ static float nGetStrokeMiter(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700421 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700422 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700423 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700424 return 1.f;
425 }
426
427 return delegate.mStrokeMiter;
428 }
429
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800430 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700431 /*package*/ static void nSetStrokeMiter(Paint thisPaint, long nativePaint, float miter) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700432 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700433 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700434 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700435 return;
436 }
437
438 delegate.mStrokeMiter = miter;
439 }
440
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800441 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700442 /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700443 int color) {
444 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800445 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800446 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700447 }
448
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800449 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700450 /*package*/ static boolean nHasShadowLayer(long paint) {
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700451 // FIXME
452 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
453 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
454 return false;
455 }
456
457 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700458 /*package*/ static boolean nIsElegantTextHeight(Paint thisPaint, long nativePaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700459 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700460 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700461 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700462 }
463
464 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700465 /*package*/ static void nSetElegantTextHeight(Paint thisPaint, long nativePaint,
466 boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700467 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700468 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700469 if (delegate == null) {
470 return;
471 }
472
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700473 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700474 }
475
476 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700477 /*package*/ static float nGetTextSize(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700478 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700479 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700480 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700481 return 1.f;
482 }
483
484 return delegate.mTextSize;
485 }
486
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800487 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700488 /*package*/ static void nSetTextSize(Paint thisPaint, long nativePaint, float textSize) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700489 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700490 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700491 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700492 return;
493 }
494
Diego Perezcdf4dc02015-09-24 14:52:59 +0100495 if (delegate.mTextSize != textSize) {
496 delegate.mTextSize = textSize;
497 delegate.updateFontObject();
498 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700499 }
500
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800501 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700502 /*package*/ static float nGetTextScaleX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700503 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700504 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700505 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700506 return 1.f;
507 }
508
509 return delegate.mTextScaleX;
510 }
511
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800512 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700513 /*package*/ static void nSetTextScaleX(Paint thisPaint, long nativePaint, float scaleX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700514 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700515 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700516 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700517 return;
518 }
519
Diego Perezcdf4dc02015-09-24 14:52:59 +0100520 if (delegate.mTextScaleX != scaleX) {
521 delegate.mTextScaleX = scaleX;
522 delegate.updateFontObject();
523 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700524 }
525
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800526 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700527 /*package*/ static float nGetTextSkewX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700528 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700529 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700530 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700531 return 1.f;
532 }
533
534 return delegate.mTextSkewX;
535 }
536
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800537 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700538 /*package*/ static void nSetTextSkewX(Paint thisPaint, long nativePaint, float skewX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700539 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700540 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700541 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700542 return;
543 }
544
Diego Perezcdf4dc02015-09-24 14:52:59 +0100545 if (delegate.mTextSkewX != skewX) {
546 delegate.mTextSkewX = skewX;
547 delegate.updateFontObject();
548 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700549 }
550
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800551 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700552 /*package*/ static float nAscent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800553 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700554 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800555 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800556 return 0;
557 }
558
559 if (delegate.mFonts.size() > 0) {
560 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
561 // Android expects negative ascent so we invert the value from Java.
562 return - javaMetrics.getAscent();
563 }
564
565 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700566 }
567
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800568 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700569 /*package*/ static float nDescent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800570 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700571 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800572 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800573 return 0;
574 }
575
576 if (delegate.mFonts.size() > 0) {
577 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
578 return javaMetrics.getDescent();
579 }
580
581 return 0;
582
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700583 }
584
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800585 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700586 /*package*/ static float nGetFontMetrics(Paint thisPaint, long nativePaint, long nativeTypeface,
587 FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700588 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700589 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700590 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700591 return 0;
592 }
593
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800594 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700595 }
596
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800597 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700598 /*package*/ static int nGetFontMetricsInt(Paint thisPaint, long nativePaint,
599 long nativeTypeface, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700600 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700601 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700602 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700603 return 0;
604 }
605
606 if (delegate.mFonts.size() > 0) {
607 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
608 if (fmi != null) {
609 // Android expects negative ascent so we invert the value from Java.
610 fmi.top = - javaMetrics.getMaxAscent();
611 fmi.ascent = - javaMetrics.getAscent();
612 fmi.descent = javaMetrics.getDescent();
613 fmi.bottom = javaMetrics.getMaxDescent();
614 fmi.leading = javaMetrics.getLeading();
615 }
616
617 return javaMetrics.getHeight();
618 }
619
620 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700621 }
622
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800623 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700624 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700625 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800626
627 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700628 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800629 if (delegate == null) {
630 return 0;
631 }
632
633 int inc = count > 0 ? 1 : -1;
634
635 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800636 for (int i = index; i != index + count; i += inc, measureIndex++) {
637 int start, end;
638 if (i < index) {
639 start = i;
640 end = index;
641 } else {
642 start = index;
643 end = i;
644 }
645
646 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700647 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800648 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800649
650 if (measuredWidth != null) {
651 measuredWidth[measureIndex] = res;
652 }
653
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800654 if (res > maxWidth) {
655 // we should not return this char index, but since it's 0-based
656 // and we need to return a count, we simply return measureIndex;
657 return measureIndex;
658 }
659
660 }
661
662 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700663 }
664
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800665 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700666 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700667 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700668 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700669 return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700670 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700671 }
672
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800673 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700674 /*package*/ static long nInit() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700675 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800676 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700677 }
678
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800679 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700680 /*package*/ static long nInitWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700681 // get the delegate from the native int.
682 Paint_Delegate delegate = sManager.getDelegate(paint);
683 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700684 return 0;
685 }
686
687 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800688 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700689 }
690
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800691 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700692 /*package*/ static void nReset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700693 // get the delegate from the native int.
694 Paint_Delegate delegate = sManager.getDelegate(native_object);
695 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700696 return;
697 }
698
699 delegate.reset();
700 }
701
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800702 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700703 /*package*/ static void nSet(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700704 // get the delegate from the native int.
705 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
706 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700707 return;
708 }
709
710 // get the delegate from the native int.
711 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
712 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700713 return;
714 }
715
716 delegate_dst.set(delegate_src);
717 }
718
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800719 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700720 /*package*/ static int nGetStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700721 // get the delegate from the native int.
722 Paint_Delegate delegate = sManager.getDelegate(native_object);
723 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700724 return 0;
725 }
726
727 return delegate.mStyle;
728 }
729
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800730 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700731 /*package*/ static void nSetStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700732 // get the delegate from the native int.
733 Paint_Delegate delegate = sManager.getDelegate(native_object);
734 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700735 return;
736 }
737
738 delegate.mStyle = style;
739 }
740
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800741 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700742 /*package*/ static int nGetStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700743 // get the delegate from the native int.
744 Paint_Delegate delegate = sManager.getDelegate(native_object);
745 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700746 return 0;
747 }
748
749 return delegate.mCap;
750 }
751
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800752 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700753 /*package*/ static void nSetStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700754 // get the delegate from the native int.
755 Paint_Delegate delegate = sManager.getDelegate(native_object);
756 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700757 return;
758 }
759
760 delegate.mCap = cap;
761 }
762
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800763 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700764 /*package*/ static int nGetStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700765 // get the delegate from the native int.
766 Paint_Delegate delegate = sManager.getDelegate(native_object);
767 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700768 return 0;
769 }
770
771 return delegate.mJoin;
772 }
773
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800774 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700775 /*package*/ static void nSetStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700776 // get the delegate from the native int.
777 Paint_Delegate delegate = sManager.getDelegate(native_object);
778 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700779 return;
780 }
781
782 delegate.mJoin = join;
783 }
784
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800785 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700786 /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800787 Paint_Delegate paint = sManager.getDelegate(native_object);
788 if (paint == null) {
789 return false;
790 }
791
792 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
793 if (srcPath == null) {
794 return true;
795 }
796
797 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
798 if (dstPath == null) {
799 return true;
800 }
801
802 Stroke stroke = paint.getJavaStroke();
803 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
804
805 dstPath.setJavaShape(strokeShape);
806
807 // FIXME figure out the return value?
808 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700809 }
810
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800811 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700812 /*package*/ static long nSetShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700813 // get the delegate from the native int.
814 Paint_Delegate delegate = sManager.getDelegate(native_object);
815 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700816 return shader;
817 }
818
Xavier Ducrohet91672792011-02-22 11:54:37 -0800819 delegate.mShader = Shader_Delegate.getDelegate(shader);
820
821 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700822 }
823
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800824 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700825 /*package*/ static long nSetColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700826 // get the delegate from the native int.
827 Paint_Delegate delegate = sManager.getDelegate(native_object);
828 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700829 return filter;
830 }
831
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700832 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800833
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700834 // Log warning if it's not supported.
835 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800836 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800837 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800838 }
839
840 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700841 }
842
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800843 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700844 /*package*/ static long nSetXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700845 // get the delegate from the native int.
846 Paint_Delegate delegate = sManager.getDelegate(native_object);
847 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700848 return xfermode;
849 }
850
Xavier Ducrohet91672792011-02-22 11:54:37 -0800851 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
852
853 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700854 }
855
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800856 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700857 /*package*/ static long nSetPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700858 // get the delegate from the native int.
859 Paint_Delegate delegate = sManager.getDelegate(native_object);
860 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700861 return effect;
862 }
863
Xavier Ducrohet91672792011-02-22 11:54:37 -0800864 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
865
866 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700867 }
868
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800869 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700870 /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700871 // get the delegate from the native int.
872 Paint_Delegate delegate = sManager.getDelegate(native_object);
873 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700874 return maskfilter;
875 }
876
Xavier Ducrohet91672792011-02-22 11:54:37 -0800877 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800878
879 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700880 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800881 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800882 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800883 }
884
885 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700886 }
887
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800888 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700889 /*package*/ static long nSetTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700890 // get the delegate from the native int.
891 Paint_Delegate delegate = sManager.getDelegate(native_object);
892 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700893 return 0;
894 }
895
Diego Perezcdf4dc02015-09-24 14:52:59 +0100896 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
897 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
898 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
899 delegate.mNativeTypeface = typeface;
900 delegate.updateFontObject();
901 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800902 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700903 }
904
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800905 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700906 /*package*/ static long nSetRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800907 // get the delegate from the native int.
908 Paint_Delegate delegate = sManager.getDelegate(native_object);
909 if (delegate == null) {
910 return rasterizer;
911 }
912
Xavier Ducrohet91672792011-02-22 11:54:37 -0800913 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800914
915 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700916 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800917 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800918 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800919 }
920
921 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700922 }
923
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800924 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700925 /*package*/ static int nGetTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700926 // get the delegate from the native int.
927 Paint_Delegate delegate = sManager.getDelegate(native_object);
928 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700929 return 0;
930 }
931
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700932 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700933 }
934
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800935 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700936 /*package*/ static void nSetTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700937 // get the delegate from the native int.
938 Paint_Delegate delegate = sManager.getDelegate(native_object);
939 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700940 return;
941 }
942
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700943 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700944 }
945
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800946 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700947 /*package*/ static int nSetTextLocales(long native_object, String locale) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700948 // get the delegate from the native int.
949 Paint_Delegate delegate = sManager.getDelegate(native_object);
950 if (delegate == null) {
951 return 0;
952 }
953
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700954 delegate.setTextLocale(locale);
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700955 return 0;
956 }
957
958 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700959 /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
960 int mMinikinLangListId) {
961 // FIXME
962 }
963
964 @LayoutlibDelegate
965 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700966 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700967 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700968
969 if (advances != null)
970 for (int i = advancesIndex; i< advancesIndex+count; i++)
971 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700972 // get the delegate from the native int.
973 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700974 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700975 return 0.f;
976 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700977
978 // native_typeface is passed here since Framework's old implementation did not have the
979 // typeface object associated with the Paint. Since, we follow the new framework way,
980 // we store the typeface with the paint and use it directly.
981 assert (native_typeface == delegate.mNativeTypeface);
982
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700983 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800984 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700985 }
986
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800987 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700988 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700989 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700990 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700991 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700992 int count = end - start;
993 char[] buffer = TemporaryBuffer.obtain(count);
994 TextUtils.getChars(text, start, end, buffer, 0);
995
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700996 return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
997 contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700998 }
999
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001000 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001001 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001002 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
1003 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001004 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1005 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1006 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001007 }
1008
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001009 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001010 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001011 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1012 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001013 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1014 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1015 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001016 }
1017
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001018 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001019 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001020 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001021 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001022 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1023 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001024 }
1025
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001026 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001027 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001028 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001029 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001030 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1031 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001032 }
1033
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001034 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001035 /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001036 String text, int start, int end, int bidiFlags, Rect bounds) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001037 nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001038 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001039 }
1040
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001041 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001042 /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001043 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001044
1045 // get the delegate from the native int.
1046 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001047 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001048 return;
1049 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001050
1051 // assert that the typeface passed is actually the one that we had stored.
1052 assert (native_typeface == delegate.mNativeTypeface);
1053
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001054 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001055 }
1056
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001057 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001058 /*package*/ static long nGetNativeFinalizer() {
1059 synchronized (Paint_Delegate.class) {
1060 if (sFinalizer == -1) {
1061 sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
1062 sManager::removeJavaReferenceFor);
1063 }
1064 }
1065 return sFinalizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001066 }
1067
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001068 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001069 /*package*/ static float nGetLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001070 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1071 if (delegate == null) {
1072 return 0;
1073 }
1074 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001075 }
1076
1077 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001078 /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001079 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1080 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001081 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1082 if (delegate == null) {
1083 return;
1084 }
1085 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001086 }
1087
1088 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001089 /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001090 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001091 "Paint.setFontFeatureSettings() not supported.", null, null);
1092 }
1093
1094 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001095 /*package*/ static int nGetHyphenEdit(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001096 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1097 if (delegate == null) {
1098 return 0;
1099 }
1100 return delegate.mHyphenEdit;
1101 }
1102
1103 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001104 /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001105 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1106 if (delegate == null) {
1107 return;
1108 }
1109 delegate.mHyphenEdit = hyphen;
1110 }
1111
1112 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001113 /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001114 String string) {
1115 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1116 if (delegate == null) {
1117 return false;
1118 }
1119 if (string.length() == 0) {
1120 return false;
1121 }
1122 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001123 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001124 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1125 return false;
1126 }
1127 assert nativeTypeface == delegate.mNativeTypeface;
1128 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1129
1130 char c = string.charAt(0);
1131 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1132 if (font.canDisplay(c)) {
1133 return true;
1134 }
1135 }
1136 return false;
1137 }
1138
1139
1140 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001141 /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001142 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1143 boolean isRtl, int offset) {
1144 int count = end - start;
1145 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001146 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1147 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1148 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001149 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001150 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001151 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001152 sum += advances[i];
1153 }
1154 return sum;
1155 }
1156
1157 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001158 /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001159 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1160 float advance) {
1161 int count = end - start;
1162 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001163 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1164 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1165 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001166 float sum = 0;
1167 int i;
1168 for (i = 0; i < count && sum < advance; i++) {
1169 sum += advances[i];
1170 }
1171 float distanceToI = sum - advance;
1172 float distanceToIMinus1 = advance - (sum - advances[i]);
1173 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001174 }
1175
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001176 // ---- Private delegate/helper methods ----
1177
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001178 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001179 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001180 }
1181
1182 private Paint_Delegate(Paint_Delegate paint) {
1183 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001184 }
1185
1186 private void set(Paint_Delegate paint) {
1187 mFlags = paint.mFlags;
1188 mColor = paint.mColor;
1189 mStyle = paint.mStyle;
1190 mCap = paint.mCap;
1191 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001192 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001193
1194 boolean needsFontUpdate = false;
1195 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1196 mTypeface = paint.mTypeface;
1197 mNativeTypeface = paint.mNativeTypeface;
1198 needsFontUpdate = true;
1199 }
1200
1201 if (mTextSize != paint.mTextSize) {
1202 mTextSize = paint.mTextSize;
1203 needsFontUpdate = true;
1204 }
1205
1206 if (mTextScaleX != paint.mTextScaleX) {
1207 mTextScaleX = paint.mTextScaleX;
1208 needsFontUpdate = true;
1209 }
1210
1211 if (mTextSkewX != paint.mTextSkewX) {
1212 mTextSkewX = paint.mTextSkewX;
1213 needsFontUpdate = true;
1214 }
1215
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001216 mStrokeWidth = paint.mStrokeWidth;
1217 mStrokeMiter = paint.mStrokeMiter;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001218 mXfermode = paint.mXfermode;
1219 mColorFilter = paint.mColorFilter;
1220 mShader = paint.mShader;
1221 mPathEffect = paint.mPathEffect;
1222 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001223 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001224 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001225
1226 if (needsFontUpdate) {
1227 updateFontObject();
1228 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001229 }
1230
1231 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001232 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001233 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001234 mStyle = Paint.Style.FILL.nativeInt;
1235 mCap = Paint.Cap.BUTT.nativeInt;
1236 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001237 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001238 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001239 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001240 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001241 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001242 mTextSize = 20.f;
1243 mTextScaleX = 1.f;
1244 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001245 mXfermode = null;
1246 mColorFilter = null;
1247 mShader = null;
1248 mPathEffect = null;
1249 mMaskFilter = null;
1250 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001251 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001252 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001253 }
1254
1255 /**
1256 * Update the {@link Font} object from the typeface, text size and scaling
1257 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001258 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001259 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001260 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001261 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001262 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001263
Diego Perezcdf4dc02015-09-24 14:52:59 +01001264 if (fonts.isEmpty()) {
1265 mFonts = Collections.emptyList();
1266 return;
1267 }
1268
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001269 // create new font objects as well as FontMetrics, based on the current text size
1270 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001271 int nFonts = fonts.size();
1272 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1273 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1274 for (int i = 0; i < nFonts; i++) {
1275 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001276 if (font == null) {
1277 // If the font is null, add null to infoList. When rendering the text, if this
1278 // null is reached, a warning will be logged.
1279 infoList.add(null);
1280 continue;
1281 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001282 FontInfo info = new FontInfo();
1283 info.mFont = font.deriveFont(mTextSize);
1284 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1285 // TODO: support skew
1286 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001287 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001288 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001289 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001290 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1291
1292 infoList.add(info);
1293 }
1294
1295 mFonts = Collections.unmodifiableList(infoList);
1296 }
1297 }
1298
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001299 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1300 int advancesIndex, int bidiFlags) {
1301 return new BidiRenderer(null, this, text)
1302 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1303 }
1304
1305 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1306 int advancesIndex, boolean isRtl) {
1307 return new BidiRenderer(null, this, text)
1308 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001309 }
1310
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001311 private float getFontMetrics(FontMetrics metrics) {
1312 if (mFonts.size() > 0) {
1313 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1314 if (metrics != null) {
1315 // Android expects negative ascent so we invert the value from Java.
1316 metrics.top = - javaMetrics.getMaxAscent();
1317 metrics.ascent = - javaMetrics.getAscent();
1318 metrics.descent = javaMetrics.getDescent();
1319 metrics.bottom = javaMetrics.getMaxDescent();
1320 metrics.leading = javaMetrics.getLeading();
1321 }
1322
1323 return javaMetrics.getHeight();
1324 }
1325
1326 return 0;
1327 }
1328
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001329 private void setTextLocale(String locale) {
1330 mLocale = new Locale(locale);
1331 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001332
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001333 private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001334 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001335 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001336 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001337 return;
1338 }
1339
1340 if (flagValue) {
1341 delegate.mFlags |= flagMask;
1342 } else {
1343 delegate.mFlags &= ~flagMask;
1344 }
1345 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001346}