blob: 839c1823dad8e040db95472a59dcb3ce8084573c [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
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800230 /**
231 * Returns the {@link Shader} delegate or null if none have been set
232 *
233 * @return the delegate or null.
234 */
235 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800236 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700237 }
238
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800239 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800240 * Returns the {@link MaskFilter} delegate or null if none have been set
241 *
242 * @return the delegate or null.
243 */
244 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800245 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800246 }
247
248 /**
249 * Returns the {@link Rasterizer} delegate or null if none have been set
250 *
251 * @return the delegate or null.
252 */
253 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800254 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700255 }
256
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700257 // ---- native methods ----
258
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800259 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700260 /*package*/ static int nGetFlags(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700261 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700262 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700263 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700264 return 0;
265 }
266
267 return delegate.mFlags;
268 }
269
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700270
271
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800272 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700273 /*package*/ static void nSetFlags(Paint thisPaint, long nativePaint, int flags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700274 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700275 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700276 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700277 return;
278 }
279
280 delegate.mFlags = flags;
281 }
282
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800283 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700284 /*package*/ static void nSetFilterBitmap(Paint thisPaint, long nativePaint, boolean filter) {
285 setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700286 }
287
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800288 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700289 /*package*/ static int nGetHinting(Paint thisPaint, long nativePaint) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700290 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700291 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700292 if (delegate == null) {
293 return Paint.HINTING_ON;
294 }
295
296 return delegate.mHintingMode;
297 }
298
299 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700300 /*package*/ static void nSetHinting(Paint thisPaint, long nativePaint, int mode) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700301 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700302 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700303 if (delegate == null) {
304 return;
305 }
306
307 delegate.mHintingMode = mode;
308 }
309
310 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700311 /*package*/ static void nSetAntiAlias(Paint thisPaint, long nativePaint, boolean aa) {
312 setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700313 }
314
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800315 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700316 /*package*/ static void nSetSubpixelText(Paint thisPaint, long nativePaint,
317 boolean subpixelText) {
318 setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700319 }
320
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800321 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700322 /*package*/ static void nSetUnderlineText(Paint thisPaint, long nativePaint,
323 boolean underlineText) {
324 setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700325 }
326
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800327 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700328 /*package*/ static void nSetStrikeThruText(Paint thisPaint, long nativePaint,
329 boolean strikeThruText) {
330 setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700331 }
332
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800333 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700334 /*package*/ static void nSetFakeBoldText(Paint thisPaint, long nativePaint,
335 boolean fakeBoldText) {
336 setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700337 }
338
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800339 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700340 /*package*/ static void nSetDither(Paint thisPaint, long nativePaint, boolean dither) {
341 setFlag(nativePaint, Paint.DITHER_FLAG, dither);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700342 }
343
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800344 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700345 /*package*/ static void nSetLinearText(Paint thisPaint, long nativePaint, boolean linearText) {
346 setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700347 }
348
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800349 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700350 /*package*/ static int nGetColor(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700351 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700352 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700353 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700354 return 0;
355 }
356
357 return delegate.mColor;
358 }
359
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800360 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700361 /*package*/ static void nSetColor(Paint thisPaint, long nativePaint, int color) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700362 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700363 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700364 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700365 return;
366 }
367
368 delegate.mColor = color;
369 }
370
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800371 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700372 /*package*/ static int nGetAlpha(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700373 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700374 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700375 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700376 return 0;
377 }
378
Xavier Ducrohet66225222010-12-21 01:33:04 -0800379 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 }
381
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800382 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700383 /*package*/ static void nSetAlpha(Paint thisPaint, long nativePaint, int a) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700384 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700385 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700386 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700387 return;
388 }
389
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800390 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700391 }
392
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800393 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700394 /*package*/ static float nGetStrokeWidth(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700395 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700396 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700397 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700398 return 1.f;
399 }
400
401 return delegate.mStrokeWidth;
402 }
403
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800404 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700405 /*package*/ static void nSetStrokeWidth(Paint thisPaint, long nativePaint, float width) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700406 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700407 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700408 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700409 return;
410 }
411
412 delegate.mStrokeWidth = width;
413 }
414
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800415 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700416 /*package*/ static float nGetStrokeMiter(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700417 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700418 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700419 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700420 return 1.f;
421 }
422
423 return delegate.mStrokeMiter;
424 }
425
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800426 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700427 /*package*/ static void nSetStrokeMiter(Paint thisPaint, long nativePaint, float miter) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700428 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700429 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700430 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700431 return;
432 }
433
434 delegate.mStrokeMiter = miter;
435 }
436
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800437 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700438 /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700439 int color) {
440 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800441 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800442 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700443 }
444
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800445 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700446 /*package*/ static boolean nHasShadowLayer(long paint) {
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700447 // FIXME
448 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
449 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
450 return false;
451 }
452
453 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700454 /*package*/ static boolean nIsElegantTextHeight(Paint thisPaint, long nativePaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700455 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700456 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700457 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700458 }
459
460 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700461 /*package*/ static void nSetElegantTextHeight(Paint thisPaint, long nativePaint,
462 boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700463 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700464 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700465 if (delegate == null) {
466 return;
467 }
468
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700469 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700470 }
471
472 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700473 /*package*/ static float nGetTextSize(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700474 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700475 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700476 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700477 return 1.f;
478 }
479
480 return delegate.mTextSize;
481 }
482
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800483 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700484 /*package*/ static void nSetTextSize(Paint thisPaint, long nativePaint, float textSize) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700485 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700486 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700487 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700488 return;
489 }
490
Diego Perezcdf4dc02015-09-24 14:52:59 +0100491 if (delegate.mTextSize != textSize) {
492 delegate.mTextSize = textSize;
493 delegate.updateFontObject();
494 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700495 }
496
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800497 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700498 /*package*/ static float nGetTextScaleX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700499 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700500 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700501 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700502 return 1.f;
503 }
504
505 return delegate.mTextScaleX;
506 }
507
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800508 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700509 /*package*/ static void nSetTextScaleX(Paint thisPaint, long nativePaint, float scaleX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700510 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700511 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700512 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700513 return;
514 }
515
Diego Perezcdf4dc02015-09-24 14:52:59 +0100516 if (delegate.mTextScaleX != scaleX) {
517 delegate.mTextScaleX = scaleX;
518 delegate.updateFontObject();
519 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700520 }
521
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800522 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700523 /*package*/ static float nGetTextSkewX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700524 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700525 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700526 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700527 return 1.f;
528 }
529
530 return delegate.mTextSkewX;
531 }
532
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800533 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700534 /*package*/ static void nSetTextSkewX(Paint thisPaint, long nativePaint, float skewX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700535 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700536 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700537 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700538 return;
539 }
540
Diego Perezcdf4dc02015-09-24 14:52:59 +0100541 if (delegate.mTextSkewX != skewX) {
542 delegate.mTextSkewX = skewX;
543 delegate.updateFontObject();
544 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700545 }
546
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800547 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700548 /*package*/ static float nAscent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800549 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700550 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800551 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800552 return 0;
553 }
554
555 if (delegate.mFonts.size() > 0) {
556 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
557 // Android expects negative ascent so we invert the value from Java.
558 return - javaMetrics.getAscent();
559 }
560
561 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700562 }
563
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800564 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700565 /*package*/ static float nDescent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800566 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700567 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800568 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800569 return 0;
570 }
571
572 if (delegate.mFonts.size() > 0) {
573 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
574 return javaMetrics.getDescent();
575 }
576
577 return 0;
578
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700579 }
580
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800581 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700582 /*package*/ static float nGetFontMetrics(Paint thisPaint, long nativePaint, long nativeTypeface,
583 FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700584 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700585 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700586 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700587 return 0;
588 }
589
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800590 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700591 }
592
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800593 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700594 /*package*/ static int nGetFontMetricsInt(Paint thisPaint, long nativePaint,
595 long nativeTypeface, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700596 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700597 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700598 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700599 return 0;
600 }
601
602 if (delegate.mFonts.size() > 0) {
603 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
604 if (fmi != null) {
605 // Android expects negative ascent so we invert the value from Java.
606 fmi.top = - javaMetrics.getMaxAscent();
607 fmi.ascent = - javaMetrics.getAscent();
608 fmi.descent = javaMetrics.getDescent();
609 fmi.bottom = javaMetrics.getMaxDescent();
610 fmi.leading = javaMetrics.getLeading();
611 }
612
613 return javaMetrics.getHeight();
614 }
615
616 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700617 }
618
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800619 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700620 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700621 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800622
623 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700624 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800625 if (delegate == null) {
626 return 0;
627 }
628
629 int inc = count > 0 ? 1 : -1;
630
631 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800632 for (int i = index; i != index + count; i += inc, measureIndex++) {
633 int start, end;
634 if (i < index) {
635 start = i;
636 end = index;
637 } else {
638 start = index;
639 end = i;
640 }
641
642 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700643 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800644 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800645
646 if (measuredWidth != null) {
647 measuredWidth[measureIndex] = res;
648 }
649
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800650 if (res > maxWidth) {
651 // we should not return this char index, but since it's 0-based
652 // and we need to return a count, we simply return measureIndex;
653 return measureIndex;
654 }
655
656 }
657
658 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700659 }
660
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800661 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700662 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700663 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700664 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700665 return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700666 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700667 }
668
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800669 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700670 /*package*/ static long nInit() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700671 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800672 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700673 }
674
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800675 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700676 /*package*/ static long nInitWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700677 // get the delegate from the native int.
678 Paint_Delegate delegate = sManager.getDelegate(paint);
679 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700680 return 0;
681 }
682
683 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800684 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700685 }
686
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800687 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700688 /*package*/ static void nReset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700689 // get the delegate from the native int.
690 Paint_Delegate delegate = sManager.getDelegate(native_object);
691 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700692 return;
693 }
694
695 delegate.reset();
696 }
697
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800698 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700699 /*package*/ static void nSet(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700700 // get the delegate from the native int.
701 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
702 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700703 return;
704 }
705
706 // get the delegate from the native int.
707 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
708 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700709 return;
710 }
711
712 delegate_dst.set(delegate_src);
713 }
714
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800715 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700716 /*package*/ static int nGetStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700717 // get the delegate from the native int.
718 Paint_Delegate delegate = sManager.getDelegate(native_object);
719 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700720 return 0;
721 }
722
723 return delegate.mStyle;
724 }
725
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800726 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700727 /*package*/ static void nSetStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700728 // get the delegate from the native int.
729 Paint_Delegate delegate = sManager.getDelegate(native_object);
730 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700731 return;
732 }
733
734 delegate.mStyle = style;
735 }
736
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800737 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700738 /*package*/ static int nGetStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700739 // get the delegate from the native int.
740 Paint_Delegate delegate = sManager.getDelegate(native_object);
741 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700742 return 0;
743 }
744
745 return delegate.mCap;
746 }
747
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800748 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700749 /*package*/ static void nSetStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700750 // get the delegate from the native int.
751 Paint_Delegate delegate = sManager.getDelegate(native_object);
752 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700753 return;
754 }
755
756 delegate.mCap = cap;
757 }
758
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800759 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700760 /*package*/ static int nGetStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700761 // get the delegate from the native int.
762 Paint_Delegate delegate = sManager.getDelegate(native_object);
763 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700764 return 0;
765 }
766
767 return delegate.mJoin;
768 }
769
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800770 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700771 /*package*/ static void nSetStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700772 // get the delegate from the native int.
773 Paint_Delegate delegate = sManager.getDelegate(native_object);
774 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700775 return;
776 }
777
778 delegate.mJoin = join;
779 }
780
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800781 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700782 /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800783 Paint_Delegate paint = sManager.getDelegate(native_object);
784 if (paint == null) {
785 return false;
786 }
787
788 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
789 if (srcPath == null) {
790 return true;
791 }
792
793 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
794 if (dstPath == null) {
795 return true;
796 }
797
798 Stroke stroke = paint.getJavaStroke();
799 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
800
801 dstPath.setJavaShape(strokeShape);
802
803 // FIXME figure out the return value?
804 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700805 }
806
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800807 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700808 /*package*/ static long nSetShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700809 // get the delegate from the native int.
810 Paint_Delegate delegate = sManager.getDelegate(native_object);
811 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700812 return shader;
813 }
814
Xavier Ducrohet91672792011-02-22 11:54:37 -0800815 delegate.mShader = Shader_Delegate.getDelegate(shader);
816
817 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700818 }
819
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800820 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700821 /*package*/ static long nSetColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700822 // get the delegate from the native int.
823 Paint_Delegate delegate = sManager.getDelegate(native_object);
824 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700825 return filter;
826 }
827
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700828 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800829
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700830 // Log warning if it's not supported.
831 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800832 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800833 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800834 }
835
836 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700837 }
838
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800839 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700840 /*package*/ static long nSetXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700841 // get the delegate from the native int.
842 Paint_Delegate delegate = sManager.getDelegate(native_object);
843 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700844 return xfermode;
845 }
846
Xavier Ducrohet91672792011-02-22 11:54:37 -0800847 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
848
849 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700850 }
851
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800852 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700853 /*package*/ static long nSetPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700854 // get the delegate from the native int.
855 Paint_Delegate delegate = sManager.getDelegate(native_object);
856 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700857 return effect;
858 }
859
Xavier Ducrohet91672792011-02-22 11:54:37 -0800860 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
861
862 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700863 }
864
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800865 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700866 /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700867 // get the delegate from the native int.
868 Paint_Delegate delegate = sManager.getDelegate(native_object);
869 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700870 return maskfilter;
871 }
872
Xavier Ducrohet91672792011-02-22 11:54:37 -0800873 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800874
875 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700876 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800877 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800878 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800879 }
880
881 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700882 }
883
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800884 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700885 /*package*/ static long nSetTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700886 // get the delegate from the native int.
887 Paint_Delegate delegate = sManager.getDelegate(native_object);
888 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700889 return 0;
890 }
891
Diego Perezcdf4dc02015-09-24 14:52:59 +0100892 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
893 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
894 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
895 delegate.mNativeTypeface = typeface;
896 delegate.updateFontObject();
897 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800898 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700899 }
900
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800901 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700902 /*package*/ static long nSetRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800903 // get the delegate from the native int.
904 Paint_Delegate delegate = sManager.getDelegate(native_object);
905 if (delegate == null) {
906 return rasterizer;
907 }
908
Xavier Ducrohet91672792011-02-22 11:54:37 -0800909 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800910
911 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700912 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800913 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800914 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800915 }
916
917 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700918 }
919
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800920 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700921 /*package*/ static int nGetTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700922 // get the delegate from the native int.
923 Paint_Delegate delegate = sManager.getDelegate(native_object);
924 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700925 return 0;
926 }
927
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700928 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700929 }
930
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800931 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700932 /*package*/ static void nSetTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700933 // get the delegate from the native int.
934 Paint_Delegate delegate = sManager.getDelegate(native_object);
935 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700936 return;
937 }
938
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700939 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700940 }
941
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800942 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700943 /*package*/ static int nSetTextLocales(long native_object, String locale) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700944 // get the delegate from the native int.
945 Paint_Delegate delegate = sManager.getDelegate(native_object);
946 if (delegate == null) {
947 return 0;
948 }
949
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700950 delegate.setTextLocale(locale);
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700951 return 0;
952 }
953
954 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700955 /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
956 int mMinikinLangListId) {
957 // FIXME
958 }
959
960 @LayoutlibDelegate
961 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700962 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700963 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700964
965 if (advances != null)
966 for (int i = advancesIndex; i< advancesIndex+count; i++)
967 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700968 // get the delegate from the native int.
969 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700970 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700971 return 0.f;
972 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700973
974 // native_typeface is passed here since Framework's old implementation did not have the
975 // typeface object associated with the Paint. Since, we follow the new framework way,
976 // we store the typeface with the paint and use it directly.
977 assert (native_typeface == delegate.mNativeTypeface);
978
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700979 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800980 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700981 }
982
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800983 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700984 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700985 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700986 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700987 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700988 int count = end - start;
989 char[] buffer = TemporaryBuffer.obtain(count);
990 TextUtils.getChars(text, start, end, buffer, 0);
991
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700992 return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
993 contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700994 }
995
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800996 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700997 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700998 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
999 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001000 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1001 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1002 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001003 }
1004
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001005 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001006 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001007 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1008 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001009 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1010 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1011 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001012 }
1013
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001014 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001015 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001016 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001017 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001018 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1019 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001020 }
1021
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001022 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001023 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001024 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001025 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001026 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1027 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001028 }
1029
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001030 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001031 /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001032 String text, int start, int end, int bidiFlags, Rect bounds) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001033 nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001034 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001035 }
1036
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001037 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001038 /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001039 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001040
1041 // get the delegate from the native int.
1042 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001043 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001044 return;
1045 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001046
1047 // assert that the typeface passed is actually the one that we had stored.
1048 assert (native_typeface == delegate.mNativeTypeface);
1049
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001050 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001051 }
1052
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001053 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001054 /*package*/ static long nGetNativeFinalizer() {
1055 synchronized (Paint_Delegate.class) {
1056 if (sFinalizer == -1) {
1057 sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
1058 sManager::removeJavaReferenceFor);
1059 }
1060 }
1061 return sFinalizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001062 }
1063
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001064 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001065 /*package*/ static float nGetLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001066 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1067 if (delegate == null) {
1068 return 0;
1069 }
1070 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001071 }
1072
1073 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001074 /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001075 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1076 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001077 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1078 if (delegate == null) {
1079 return;
1080 }
1081 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001082 }
1083
1084 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001085 /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001086 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001087 "Paint.setFontFeatureSettings() not supported.", null, null);
1088 }
1089
1090 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001091 /*package*/ static int nGetHyphenEdit(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001092 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1093 if (delegate == null) {
1094 return 0;
1095 }
1096 return delegate.mHyphenEdit;
1097 }
1098
1099 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001100 /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001101 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1102 if (delegate == null) {
1103 return;
1104 }
1105 delegate.mHyphenEdit = hyphen;
1106 }
1107
1108 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001109 /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001110 String string) {
1111 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1112 if (delegate == null) {
1113 return false;
1114 }
1115 if (string.length() == 0) {
1116 return false;
1117 }
1118 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001119 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001120 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1121 return false;
1122 }
1123 assert nativeTypeface == delegate.mNativeTypeface;
1124 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1125
1126 char c = string.charAt(0);
1127 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1128 if (font.canDisplay(c)) {
1129 return true;
1130 }
1131 }
1132 return false;
1133 }
1134
1135
1136 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001137 /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001138 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1139 boolean isRtl, int offset) {
1140 int count = end - start;
1141 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001142 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1143 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1144 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001145 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001146 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001147 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001148 sum += advances[i];
1149 }
1150 return sum;
1151 }
1152
1153 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001154 /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001155 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1156 float advance) {
1157 int count = end - start;
1158 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001159 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1160 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1161 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001162 float sum = 0;
1163 int i;
1164 for (i = 0; i < count && sum < advance; i++) {
1165 sum += advances[i];
1166 }
1167 float distanceToI = sum - advance;
1168 float distanceToIMinus1 = advance - (sum - advances[i]);
1169 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001170 }
1171
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001172 // ---- Private delegate/helper methods ----
1173
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001174 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001175 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001176 }
1177
1178 private Paint_Delegate(Paint_Delegate paint) {
1179 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001180 }
1181
1182 private void set(Paint_Delegate paint) {
1183 mFlags = paint.mFlags;
1184 mColor = paint.mColor;
1185 mStyle = paint.mStyle;
1186 mCap = paint.mCap;
1187 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001188 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001189
1190 boolean needsFontUpdate = false;
1191 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1192 mTypeface = paint.mTypeface;
1193 mNativeTypeface = paint.mNativeTypeface;
1194 needsFontUpdate = true;
1195 }
1196
1197 if (mTextSize != paint.mTextSize) {
1198 mTextSize = paint.mTextSize;
1199 needsFontUpdate = true;
1200 }
1201
1202 if (mTextScaleX != paint.mTextScaleX) {
1203 mTextScaleX = paint.mTextScaleX;
1204 needsFontUpdate = true;
1205 }
1206
1207 if (mTextSkewX != paint.mTextSkewX) {
1208 mTextSkewX = paint.mTextSkewX;
1209 needsFontUpdate = true;
1210 }
1211
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001212 mStrokeWidth = paint.mStrokeWidth;
1213 mStrokeMiter = paint.mStrokeMiter;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001214 mXfermode = paint.mXfermode;
1215 mColorFilter = paint.mColorFilter;
1216 mShader = paint.mShader;
1217 mPathEffect = paint.mPathEffect;
1218 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001219 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001220 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001221
1222 if (needsFontUpdate) {
1223 updateFontObject();
1224 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001225 }
1226
1227 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001228 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001229 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001230 mStyle = Paint.Style.FILL.nativeInt;
1231 mCap = Paint.Cap.BUTT.nativeInt;
1232 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001233 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001234 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001235 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001236 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001237 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001238 mTextSize = 20.f;
1239 mTextScaleX = 1.f;
1240 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001241 mXfermode = null;
1242 mColorFilter = null;
1243 mShader = null;
1244 mPathEffect = null;
1245 mMaskFilter = null;
1246 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001247 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001248 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001249 }
1250
1251 /**
1252 * Update the {@link Font} object from the typeface, text size and scaling
1253 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001254 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001255 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001256 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001257 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001258 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001259
Diego Perezcdf4dc02015-09-24 14:52:59 +01001260 if (fonts.isEmpty()) {
1261 mFonts = Collections.emptyList();
1262 return;
1263 }
1264
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001265 // create new font objects as well as FontMetrics, based on the current text size
1266 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001267 int nFonts = fonts.size();
1268 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1269 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1270 for (int i = 0; i < nFonts; i++) {
1271 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001272 if (font == null) {
1273 // If the font is null, add null to infoList. When rendering the text, if this
1274 // null is reached, a warning will be logged.
1275 infoList.add(null);
1276 continue;
1277 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001278 FontInfo info = new FontInfo();
1279 info.mFont = font.deriveFont(mTextSize);
1280 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1281 // TODO: support skew
1282 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001283 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001284 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001285 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001286 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1287
1288 infoList.add(info);
1289 }
1290
1291 mFonts = Collections.unmodifiableList(infoList);
1292 }
1293 }
1294
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001295 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1296 int advancesIndex, int bidiFlags) {
1297 return new BidiRenderer(null, this, text)
1298 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1299 }
1300
1301 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1302 int advancesIndex, boolean isRtl) {
1303 return new BidiRenderer(null, this, text)
1304 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001305 }
1306
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001307 private float getFontMetrics(FontMetrics metrics) {
1308 if (mFonts.size() > 0) {
1309 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1310 if (metrics != null) {
1311 // Android expects negative ascent so we invert the value from Java.
1312 metrics.top = - javaMetrics.getMaxAscent();
1313 metrics.ascent = - javaMetrics.getAscent();
1314 metrics.descent = javaMetrics.getDescent();
1315 metrics.bottom = javaMetrics.getMaxDescent();
1316 metrics.leading = javaMetrics.getLeading();
1317 }
1318
1319 return javaMetrics.getHeight();
1320 }
1321
1322 return 0;
1323 }
1324
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001325 private void setTextLocale(String locale) {
1326 mLocale = new Locale(locale);
1327 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001328
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001329 private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001330 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001331 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001332 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001333 return;
1334 }
1335
1336 if (flagValue) {
1337 delegate.mFlags |= flagMask;
1338 } else {
1339 delegate.mFlags &= ~flagMask;
1340 }
1341 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001342}