blob: e68d8b3e9f937e7adb03f01a8f6e05962baa1710 [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.
Jerome Gaillard989f4cb2016-11-24 21:51:22 +000093 private float mWordSpacing; // not used in actual text rendering.
Deepanshu Gupta8916b212014-06-11 15:40:47 -070094 // Variant of the font. A paint's variant can only be compact or elegant.
95 private FontVariant mFontVariant = FontVariant.COMPACT;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070096
Jerome Gaillard989f4cb2016-11-24 21:51:22 +000097 private int mPorterDuffMode = Xfermode.DEFAULT;
Xavier Ducrohet91672792011-02-22 11:54:37 -080098 private ColorFilter_Delegate mColorFilter;
99 private Shader_Delegate mShader;
100 private PathEffect_Delegate mPathEffect;
101 private MaskFilter_Delegate mMaskFilter;
102 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -0700103
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700104 private Locale mLocale = Locale.getDefault();
105
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700106 // Used only to assert invariants.
107 public long mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700108
109 // ---- Public Helper methods ----
110
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -0700111 @Nullable
Narayan Kamath633d6882014-01-27 14:24:16 +0000112 public static Paint_Delegate getDelegate(long native_paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700113 return sManager.getDelegate(native_paint);
114 }
115
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700116 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700117 * Returns the list of {@link Font} objects.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700118 */
119 public List<FontInfo> getFonts() {
120 return mFonts;
121 }
122
Xavier Ducroheta313b652010-11-01 18:45:20 -0700123 public boolean isAntiAliased() {
124 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
125 }
126
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700127 public boolean isFilterBitmap() {
128 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
129 }
130
131 public int getStyle() {
132 return mStyle;
133 }
134
135 public int getColor() {
136 return mColor;
137 }
138
Xavier Ducrohet66225222010-12-21 01:33:04 -0800139 public int getAlpha() {
140 return mColor >>> 24;
141 }
142
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800143 public void setAlpha(int alpha) {
144 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
145 }
146
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700147 public int getTextAlign() {
148 return mTextAlign;
149 }
150
151 public float getStrokeWidth() {
152 return mStrokeWidth;
153 }
154
Xavier Ducrohet66225222010-12-21 01:33:04 -0800155 /**
156 * returns the value of stroke miter needed by the java api.
157 */
158 public float getJavaStrokeMiter() {
Diego Pereza1c60152015-12-18 16:01:24 +0000159 return mStrokeMiter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700160 }
161
162 public int getJavaCap() {
163 switch (Paint.sCapArray[mCap]) {
164 case BUTT:
165 return BasicStroke.CAP_BUTT;
166 case ROUND:
167 return BasicStroke.CAP_ROUND;
168 default:
169 case SQUARE:
170 return BasicStroke.CAP_SQUARE;
171 }
172 }
173
174 public int getJavaJoin() {
175 switch (Paint.sJoinArray[mJoin]) {
176 default:
177 case MITER:
178 return BasicStroke.JOIN_MITER;
179 case ROUND:
180 return BasicStroke.JOIN_ROUND;
181 case BEVEL:
182 return BasicStroke.JOIN_BEVEL;
183 }
184 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700185
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800186 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800187 if (mPathEffect != null) {
188 if (mPathEffect.isSupported()) {
189 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800190 assert stroke != null;
191 if (stroke != null) {
192 return stroke;
193 }
194 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800195 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800196 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800197 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800198 }
199 }
200
201 // if no custom stroke as been set, set the default one.
202 return new BasicStroke(
203 getStrokeWidth(),
204 getJavaCap(),
205 getJavaJoin(),
206 getJavaStrokeMiter());
207 }
208
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800209 /**
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000210 * Returns the {@link PorterDuff.Mode} as an int
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800211 */
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000212 public int getPorterDuffMode() {
213 return mPorterDuffMode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700214 }
215
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800216 /**
217 * Returns the {@link ColorFilter} delegate or null if none have been set
218 *
219 * @return the delegate or null.
220 */
221 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800222 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700223 }
224
Diego Pereze4cf18f2016-02-23 12:19:11 +0000225 public void setColorFilter(long colorFilterPtr) {
226 mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
227 }
228
Diego Perez741ef6a2016-03-01 16:20:43 +0000229 public void setShader(long shaderPtr) {
230 mShader = Shader_Delegate.getDelegate(shaderPtr);
231 }
232
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800233 /**
234 * Returns the {@link Shader} delegate or null if none have been set
235 *
236 * @return the delegate or null.
237 */
238 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800239 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700240 }
241
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800242 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800243 * Returns the {@link MaskFilter} delegate or null if none have been set
244 *
245 * @return the delegate or null.
246 */
247 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800248 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800249 }
250
251 /**
252 * Returns the {@link Rasterizer} delegate or null if none have been set
253 *
254 * @return the delegate or null.
255 */
256 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800257 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700258 }
259
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700260 // ---- native methods ----
261
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800262 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000263 /*package*/ static int nGetFlags(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700264 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700265 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700266 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700267 return 0;
268 }
269
270 return delegate.mFlags;
271 }
272
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700273
274
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800275 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000276 /*package*/ static void nSetFlags(long nativePaint, int flags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700277 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700278 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700279 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700280 return;
281 }
282
283 delegate.mFlags = flags;
284 }
285
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800286 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000287 /*package*/ static void nSetFilterBitmap(long nativePaint, boolean filter) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700288 setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700289 }
290
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800291 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000292 /*package*/ static int nGetHinting(long nativePaint) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700293 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700294 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700295 if (delegate == null) {
296 return Paint.HINTING_ON;
297 }
298
299 return delegate.mHintingMode;
300 }
301
302 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000303 /*package*/ static void nSetHinting(long nativePaint, int mode) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700304 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700305 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700306 if (delegate == null) {
307 return;
308 }
309
310 delegate.mHintingMode = mode;
311 }
312
313 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000314 /*package*/ static void nSetAntiAlias(long nativePaint, boolean aa) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700315 setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700316 }
317
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800318 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000319 /*package*/ static void nSetSubpixelText(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700320 boolean subpixelText) {
321 setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700322 }
323
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800324 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000325 /*package*/ static void nSetUnderlineText(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700326 boolean underlineText) {
327 setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700328 }
329
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800330 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000331 /*package*/ static void nSetStrikeThruText(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700332 boolean strikeThruText) {
333 setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700334 }
335
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800336 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000337 /*package*/ static void nSetFakeBoldText(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700338 boolean fakeBoldText) {
339 setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700340 }
341
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800342 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000343 /*package*/ static void nSetDither(long nativePaint, boolean dither) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700344 setFlag(nativePaint, Paint.DITHER_FLAG, dither);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700345 }
346
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800347 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000348 /*package*/ static void nSetLinearText(long nativePaint, boolean linearText) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700349 setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700350 }
351
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800352 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000353 /*package*/ static int nGetColor(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700354 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700355 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700356 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700357 return 0;
358 }
359
360 return delegate.mColor;
361 }
362
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800363 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000364 /*package*/ static void nSetColor(long nativePaint, int color) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700365 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700366 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700367 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700368 return;
369 }
370
371 delegate.mColor = color;
372 }
373
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800374 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000375 /*package*/ static int nGetAlpha(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700376 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700377 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700378 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700379 return 0;
380 }
381
Xavier Ducrohet66225222010-12-21 01:33:04 -0800382 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700383 }
384
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800385 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000386 /*package*/ static void nSetAlpha(long nativePaint, int a) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700387 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700388 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700389 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700390 return;
391 }
392
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800393 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700394 }
395
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800396 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000397 /*package*/ static float nGetStrokeWidth(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700398 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700399 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700400 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700401 return 1.f;
402 }
403
404 return delegate.mStrokeWidth;
405 }
406
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800407 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000408 /*package*/ static void nSetStrokeWidth(long nativePaint, float width) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700409 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700410 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700411 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700412 return;
413 }
414
415 delegate.mStrokeWidth = width;
416 }
417
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800418 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000419 /*package*/ static float nGetStrokeMiter(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700420 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700421 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700422 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700423 return 1.f;
424 }
425
426 return delegate.mStrokeMiter;
427 }
428
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800429 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000430 /*package*/ static void nSetStrokeMiter(long nativePaint, float miter) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700431 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700432 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700433 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700434 return;
435 }
436
437 delegate.mStrokeMiter = miter;
438 }
439
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800440 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700441 /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700442 int color) {
443 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800444 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800445 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700446 }
447
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800448 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700449 /*package*/ static boolean nHasShadowLayer(long paint) {
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700450 // FIXME
451 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
452 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
453 return false;
454 }
455
456 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000457 /*package*/ static boolean nIsElegantTextHeight(long nativePaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700458 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700459 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700460 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700461 }
462
463 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000464 /*package*/ static void nSetElegantTextHeight(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700465 boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700466 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700467 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700468 if (delegate == null) {
469 return;
470 }
471
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700472 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700473 }
474
475 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000476 /*package*/ static float nGetTextSize(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700477 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700478 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700479 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700480 return 1.f;
481 }
482
483 return delegate.mTextSize;
484 }
485
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800486 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000487 /*package*/ static void nSetTextSize(long nativePaint, float textSize) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700488 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700489 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700490 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700491 return;
492 }
493
Diego Perezcdf4dc02015-09-24 14:52:59 +0100494 if (delegate.mTextSize != textSize) {
495 delegate.mTextSize = textSize;
496 delegate.updateFontObject();
497 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700498 }
499
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800500 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000501 /*package*/ static float nGetTextScaleX(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700502 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700503 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700504 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700505 return 1.f;
506 }
507
508 return delegate.mTextScaleX;
509 }
510
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800511 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000512 /*package*/ static void nSetTextScaleX(long nativePaint, float scaleX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700513 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700514 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700515 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700516 return;
517 }
518
Diego Perezcdf4dc02015-09-24 14:52:59 +0100519 if (delegate.mTextScaleX != scaleX) {
520 delegate.mTextScaleX = scaleX;
521 delegate.updateFontObject();
522 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700523 }
524
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800525 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000526 /*package*/ static float nGetTextSkewX(long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700527 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700528 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700529 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700530 return 1.f;
531 }
532
533 return delegate.mTextSkewX;
534 }
535
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800536 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000537 /*package*/ static void nSetTextSkewX(long nativePaint, float skewX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700538 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700539 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700540 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700541 return;
542 }
543
Diego Perezcdf4dc02015-09-24 14:52:59 +0100544 if (delegate.mTextSkewX != skewX) {
545 delegate.mTextSkewX = skewX;
546 delegate.updateFontObject();
547 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700548 }
549
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800550 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000551 /*package*/ static float nAscent(long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800552 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700553 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800554 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800555 return 0;
556 }
557
558 if (delegate.mFonts.size() > 0) {
559 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
560 // Android expects negative ascent so we invert the value from Java.
561 return - javaMetrics.getAscent();
562 }
563
564 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700565 }
566
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800567 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000568 /*package*/ static float nDescent(long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800569 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700570 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800571 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800572 return 0;
573 }
574
575 if (delegate.mFonts.size() > 0) {
576 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
577 return javaMetrics.getDescent();
578 }
579
580 return 0;
581
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700582 }
583
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800584 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000585 /*package*/ static float nGetFontMetrics(long nativePaint, long nativeTypeface,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700586 FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700587 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700588 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700589 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700590 return 0;
591 }
592
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800593 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700594 }
595
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800596 @LayoutlibDelegate
Jerome Gaillard7fa71f52016-11-11 12:39:34 +0000597 /*package*/ static int nGetFontMetricsInt(long nativePaint,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700598 long nativeTypeface, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700599 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700600 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700601 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700602 return 0;
603 }
604
605 if (delegate.mFonts.size() > 0) {
606 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
607 if (fmi != null) {
608 // Android expects negative ascent so we invert the value from Java.
609 fmi.top = - javaMetrics.getMaxAscent();
610 fmi.ascent = - javaMetrics.getAscent();
611 fmi.descent = javaMetrics.getDescent();
612 fmi.bottom = javaMetrics.getMaxDescent();
613 fmi.leading = javaMetrics.getLeading();
614 }
615
616 return javaMetrics.getHeight();
617 }
618
619 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700620 }
621
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800622 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700623 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700624 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800625
626 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700627 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800628 if (delegate == null) {
629 return 0;
630 }
631
632 int inc = count > 0 ? 1 : -1;
633
634 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800635 for (int i = index; i != index + count; i += inc, measureIndex++) {
636 int start, end;
637 if (i < index) {
638 start = i;
639 end = index;
640 } else {
641 start = index;
642 end = i;
643 }
644
645 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700646 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800647 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800648
649 if (measuredWidth != null) {
650 measuredWidth[measureIndex] = res;
651 }
652
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800653 if (res > maxWidth) {
654 // we should not return this char index, but since it's 0-based
655 // and we need to return a count, we simply return measureIndex;
656 return measureIndex;
657 }
658
659 }
660
661 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700662 }
663
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800664 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700665 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700666 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700667 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700668 return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700669 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700670 }
671
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800672 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700673 /*package*/ static long nInit() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700674 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800675 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700676 }
677
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800678 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700679 /*package*/ static long nInitWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700680 // get the delegate from the native int.
681 Paint_Delegate delegate = sManager.getDelegate(paint);
682 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700683 return 0;
684 }
685
686 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800687 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700688 }
689
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800690 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700691 /*package*/ static void nReset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700692 // get the delegate from the native int.
693 Paint_Delegate delegate = sManager.getDelegate(native_object);
694 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700695 return;
696 }
697
698 delegate.reset();
699 }
700
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800701 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700702 /*package*/ static void nSet(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700703 // get the delegate from the native int.
704 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
705 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700706 return;
707 }
708
709 // get the delegate from the native int.
710 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
711 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700712 return;
713 }
714
715 delegate_dst.set(delegate_src);
716 }
717
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800718 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700719 /*package*/ static int nGetStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700720 // get the delegate from the native int.
721 Paint_Delegate delegate = sManager.getDelegate(native_object);
722 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700723 return 0;
724 }
725
726 return delegate.mStyle;
727 }
728
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800729 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700730 /*package*/ static void nSetStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700731 // get the delegate from the native int.
732 Paint_Delegate delegate = sManager.getDelegate(native_object);
733 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700734 return;
735 }
736
737 delegate.mStyle = style;
738 }
739
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800740 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700741 /*package*/ static int nGetStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700742 // get the delegate from the native int.
743 Paint_Delegate delegate = sManager.getDelegate(native_object);
744 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700745 return 0;
746 }
747
748 return delegate.mCap;
749 }
750
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800751 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700752 /*package*/ static void nSetStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700753 // get the delegate from the native int.
754 Paint_Delegate delegate = sManager.getDelegate(native_object);
755 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700756 return;
757 }
758
759 delegate.mCap = cap;
760 }
761
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800762 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700763 /*package*/ static int nGetStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700764 // get the delegate from the native int.
765 Paint_Delegate delegate = sManager.getDelegate(native_object);
766 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700767 return 0;
768 }
769
770 return delegate.mJoin;
771 }
772
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800773 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700774 /*package*/ static void nSetStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700775 // get the delegate from the native int.
776 Paint_Delegate delegate = sManager.getDelegate(native_object);
777 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700778 return;
779 }
780
781 delegate.mJoin = join;
782 }
783
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800784 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700785 /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800786 Paint_Delegate paint = sManager.getDelegate(native_object);
787 if (paint == null) {
788 return false;
789 }
790
791 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
792 if (srcPath == null) {
793 return true;
794 }
795
796 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
797 if (dstPath == null) {
798 return true;
799 }
800
801 Stroke stroke = paint.getJavaStroke();
802 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
803
804 dstPath.setJavaShape(strokeShape);
805
806 // FIXME figure out the return value?
807 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700808 }
809
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800810 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700811 /*package*/ static long nSetShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700812 // get the delegate from the native int.
813 Paint_Delegate delegate = sManager.getDelegate(native_object);
814 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700815 return shader;
816 }
817
Xavier Ducrohet91672792011-02-22 11:54:37 -0800818 delegate.mShader = Shader_Delegate.getDelegate(shader);
819
820 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700821 }
822
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800823 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700824 /*package*/ static long nSetColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700825 // get the delegate from the native int.
826 Paint_Delegate delegate = sManager.getDelegate(native_object);
827 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700828 return filter;
829 }
830
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700831 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800832
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700833 // Log warning if it's not supported.
834 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800835 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800836 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800837 }
838
839 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700840 }
841
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800842 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000843 /*package*/ static void nSetXfermode(long native_object, int xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700844 Paint_Delegate delegate = sManager.getDelegate(native_object);
845 if (delegate == null) {
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000846 return;
Xavier Ducroheta313b652010-11-01 18:45:20 -0700847 }
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000848 delegate.mPorterDuffMode = xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700849 }
850
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800851 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700852 /*package*/ static long nSetPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700853 // get the delegate from the native int.
854 Paint_Delegate delegate = sManager.getDelegate(native_object);
855 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700856 return effect;
857 }
858
Xavier Ducrohet91672792011-02-22 11:54:37 -0800859 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
860
861 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700862 }
863
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800864 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700865 /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700866 // get the delegate from the native int.
867 Paint_Delegate delegate = sManager.getDelegate(native_object);
868 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700869 return maskfilter;
870 }
871
Xavier Ducrohet91672792011-02-22 11:54:37 -0800872 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800873
874 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700875 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800876 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800877 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800878 }
879
880 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700881 }
882
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800883 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700884 /*package*/ static long nSetTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700885 // get the delegate from the native int.
886 Paint_Delegate delegate = sManager.getDelegate(native_object);
887 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700888 return 0;
889 }
890
Diego Perezcdf4dc02015-09-24 14:52:59 +0100891 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
892 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
893 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
894 delegate.mNativeTypeface = typeface;
895 delegate.updateFontObject();
896 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800897 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700898 }
899
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800900 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700901 /*package*/ static long nSetRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800902 // get the delegate from the native int.
903 Paint_Delegate delegate = sManager.getDelegate(native_object);
904 if (delegate == null) {
905 return rasterizer;
906 }
907
Xavier Ducrohet91672792011-02-22 11:54:37 -0800908 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800909
910 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700911 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800912 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800913 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800914 }
915
916 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700917 }
918
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800919 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700920 /*package*/ static int nGetTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700921 // get the delegate from the native int.
922 Paint_Delegate delegate = sManager.getDelegate(native_object);
923 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700924 return 0;
925 }
926
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700927 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700928 }
929
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800930 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700931 /*package*/ static void nSetTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700932 // get the delegate from the native int.
933 Paint_Delegate delegate = sManager.getDelegate(native_object);
934 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700935 return;
936 }
937
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700938 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700939 }
940
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800941 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700942 /*package*/ static int nSetTextLocales(long native_object, String locale) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700943 // get the delegate from the native int.
944 Paint_Delegate delegate = sManager.getDelegate(native_object);
945 if (delegate == null) {
946 return 0;
947 }
948
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700949 delegate.setTextLocale(locale);
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700950 return 0;
951 }
952
953 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700954 /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
955 int mMinikinLangListId) {
956 // FIXME
957 }
958
959 @LayoutlibDelegate
960 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700961 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700962 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700963
964 if (advances != null)
965 for (int i = advancesIndex; i< advancesIndex+count; i++)
966 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700967 // get the delegate from the native int.
968 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700969 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700970 return 0.f;
971 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700972
973 // native_typeface is passed here since Framework's old implementation did not have the
974 // typeface object associated with the Paint. Since, we follow the new framework way,
975 // we store the typeface with the paint and use it directly.
976 assert (native_typeface == delegate.mNativeTypeface);
977
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700978 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800979 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700980 }
981
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800982 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700983 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700984 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700985 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700986 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700987 int count = end - start;
988 char[] buffer = TemporaryBuffer.obtain(count);
989 TextUtils.getChars(text, start, end, buffer, 0);
990
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700991 return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
992 contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700993 }
994
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800995 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000996 /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700997 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
998 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800999 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1000 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1001 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001002 }
1003
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001004 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +00001005 /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001006 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1007 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001008 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1009 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1010 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001011 }
1012
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001013 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001014 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001015 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001016 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001017 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1018 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001019 }
1020
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001021 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001022 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001023 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001024 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001025 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1026 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001027 }
1028
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001029 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001030 /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001031 String text, int start, int end, int bidiFlags, Rect bounds) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001032 nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001033 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001034 }
1035
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001036 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001037 /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001038 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001039
1040 // get the delegate from the native int.
1041 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001042 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001043 return;
1044 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001045
1046 // assert that the typeface passed is actually the one that we had stored.
1047 assert (native_typeface == delegate.mNativeTypeface);
1048
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001049 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001050 }
1051
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001052 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001053 /*package*/ static long nGetNativeFinalizer() {
1054 synchronized (Paint_Delegate.class) {
1055 if (sFinalizer == -1) {
1056 sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
1057 sManager::removeJavaReferenceFor);
1058 }
1059 }
1060 return sFinalizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001061 }
1062
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001063 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001064 /*package*/ static float nGetLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001065 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1066 if (delegate == null) {
1067 return 0;
1068 }
1069 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001070 }
1071
1072 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001073 /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001074 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1075 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001076 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1077 if (delegate == null) {
1078 return;
1079 }
1080 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001081 }
1082
1083 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +00001084 /*package*/ static float nGetWordSpacing(long nativePaint) {
1085 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1086 if (delegate == null) {
1087 return 0;
1088 }
1089 return delegate.mWordSpacing;
1090 }
1091
1092 @LayoutlibDelegate
1093 /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
1094 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1095 "Paint.setWordSpacing() not supported.", null, null);
1096 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1097 if (delegate == null) {
1098 return;
1099 }
1100 delegate.mWordSpacing = wordSpacing;
1101 }
1102
1103 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001104 /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001105 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001106 "Paint.setFontFeatureSettings() not supported.", null, null);
1107 }
1108
1109 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001110 /*package*/ static int nGetHyphenEdit(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001111 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1112 if (delegate == null) {
1113 return 0;
1114 }
1115 return delegate.mHyphenEdit;
1116 }
1117
1118 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001119 /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001120 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1121 if (delegate == null) {
1122 return;
1123 }
1124 delegate.mHyphenEdit = hyphen;
1125 }
1126
1127 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001128 /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001129 String string) {
1130 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1131 if (delegate == null) {
1132 return false;
1133 }
1134 if (string.length() == 0) {
1135 return false;
1136 }
1137 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001138 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001139 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1140 return false;
1141 }
1142 assert nativeTypeface == delegate.mNativeTypeface;
1143 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1144
1145 char c = string.charAt(0);
1146 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1147 if (font.canDisplay(c)) {
1148 return true;
1149 }
1150 }
1151 return false;
1152 }
1153
1154
1155 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001156 /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001157 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1158 boolean isRtl, int offset) {
1159 int count = end - start;
1160 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001161 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1162 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1163 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001164 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001165 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001166 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001167 sum += advances[i];
1168 }
1169 return sum;
1170 }
1171
1172 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001173 /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001174 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1175 float advance) {
1176 int count = end - start;
1177 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001178 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1179 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1180 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001181 float sum = 0;
1182 int i;
1183 for (i = 0; i < count && sum < advance; i++) {
1184 sum += advances[i];
1185 }
1186 float distanceToI = sum - advance;
1187 float distanceToIMinus1 = advance - (sum - advances[i]);
1188 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001189 }
1190
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001191 // ---- Private delegate/helper methods ----
1192
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001193 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001194 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001195 }
1196
1197 private Paint_Delegate(Paint_Delegate paint) {
1198 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001199 }
1200
1201 private void set(Paint_Delegate paint) {
1202 mFlags = paint.mFlags;
1203 mColor = paint.mColor;
1204 mStyle = paint.mStyle;
1205 mCap = paint.mCap;
1206 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001207 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001208
1209 boolean needsFontUpdate = false;
1210 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1211 mTypeface = paint.mTypeface;
1212 mNativeTypeface = paint.mNativeTypeface;
1213 needsFontUpdate = true;
1214 }
1215
1216 if (mTextSize != paint.mTextSize) {
1217 mTextSize = paint.mTextSize;
1218 needsFontUpdate = true;
1219 }
1220
1221 if (mTextScaleX != paint.mTextScaleX) {
1222 mTextScaleX = paint.mTextScaleX;
1223 needsFontUpdate = true;
1224 }
1225
1226 if (mTextSkewX != paint.mTextSkewX) {
1227 mTextSkewX = paint.mTextSkewX;
1228 needsFontUpdate = true;
1229 }
1230
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001231 mStrokeWidth = paint.mStrokeWidth;
1232 mStrokeMiter = paint.mStrokeMiter;
Jerome Gaillard989f4cb2016-11-24 21:51:22 +00001233 mPorterDuffMode = paint.mPorterDuffMode;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001234 mColorFilter = paint.mColorFilter;
1235 mShader = paint.mShader;
1236 mPathEffect = paint.mPathEffect;
1237 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001238 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001239 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001240
1241 if (needsFontUpdate) {
1242 updateFontObject();
1243 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001244 }
1245
1246 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001247 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001248 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001249 mStyle = Paint.Style.FILL.nativeInt;
1250 mCap = Paint.Cap.BUTT.nativeInt;
1251 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001252 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001253 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001254 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001255 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001256 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001257 mTextSize = 20.f;
1258 mTextScaleX = 1.f;
1259 mTextSkewX = 0.f;
Jerome Gaillard989f4cb2016-11-24 21:51:22 +00001260 mPorterDuffMode = Xfermode.DEFAULT;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001261 mColorFilter = null;
1262 mShader = null;
1263 mPathEffect = null;
1264 mMaskFilter = null;
1265 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001266 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001267 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001268 }
1269
1270 /**
1271 * Update the {@link Font} object from the typeface, text size and scaling
1272 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001273 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001274 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001275 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001276 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001277 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001278
Diego Perezcdf4dc02015-09-24 14:52:59 +01001279 if (fonts.isEmpty()) {
1280 mFonts = Collections.emptyList();
1281 return;
1282 }
1283
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001284 // create new font objects as well as FontMetrics, based on the current text size
1285 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001286 int nFonts = fonts.size();
1287 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1288 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1289 for (int i = 0; i < nFonts; i++) {
1290 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001291 if (font == null) {
1292 // If the font is null, add null to infoList. When rendering the text, if this
1293 // null is reached, a warning will be logged.
1294 infoList.add(null);
1295 continue;
1296 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001297 FontInfo info = new FontInfo();
1298 info.mFont = font.deriveFont(mTextSize);
1299 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1300 // TODO: support skew
1301 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001302 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001303 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001304 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001305 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1306
1307 infoList.add(info);
1308 }
1309
1310 mFonts = Collections.unmodifiableList(infoList);
1311 }
1312 }
1313
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001314 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1315 int advancesIndex, int bidiFlags) {
1316 return new BidiRenderer(null, this, text)
1317 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1318 }
1319
1320 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1321 int advancesIndex, boolean isRtl) {
1322 return new BidiRenderer(null, this, text)
1323 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001324 }
1325
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001326 private float getFontMetrics(FontMetrics metrics) {
1327 if (mFonts.size() > 0) {
1328 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1329 if (metrics != null) {
1330 // Android expects negative ascent so we invert the value from Java.
1331 metrics.top = - javaMetrics.getMaxAscent();
1332 metrics.ascent = - javaMetrics.getAscent();
1333 metrics.descent = javaMetrics.getDescent();
1334 metrics.bottom = javaMetrics.getMaxDescent();
1335 metrics.leading = javaMetrics.getLeading();
1336 }
1337
1338 return javaMetrics.getHeight();
1339 }
1340
1341 return 0;
1342 }
1343
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001344 private void setTextLocale(String locale) {
1345 mLocale = new Locale(locale);
1346 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001347
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001348 private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001349 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001350 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001351 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001352 return;
1353 }
1354
1355 if (flagValue) {
1356 delegate.mFlags |= flagMask;
1357 } else {
1358 delegate.mFlags &= ~flagMask;
1359 }
1360 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001361}