blob: dbd45c4f68be5b9b4cf995eff94e5da16f94404c [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
42/**
43 * Delegate implementing the native methods of android.graphics.Paint
44 *
45 * Through the layoutlib_create tool, the original native methods of Paint have been replaced
46 * by calls to methods of the same name in this delegate class.
47 *
48 * This class behaves like the original native implementation, but in Java, keeping previously
49 * native data into its own objects and mapping them to int that are sent back and forth between
50 * it and the original Paint class.
51 *
52 * @see DelegateManager
53 *
54 */
55public class Paint_Delegate {
56
57 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -070058 * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070059 */
Xavier Ducrohet37f21802010-11-01 16:17:18 -070060 /*package*/ static final class FontInfo {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070061 Font mFont;
62 java.awt.FontMetrics mMetrics;
63 }
64
65 // ---- delegate manager ----
66 private static final DelegateManager<Paint_Delegate> sManager =
Xavier Ducrohetb2de8392011-02-23 16:51:08 -080067 new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070068
69 // ---- delegate helper data ----
Deepanshu Gupta382256f2014-08-09 14:14:32 -070070
71 // This list can contain null elements.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070072 private List<FontInfo> mFonts;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070073
74 // ---- delegate data ----
75 private int mFlags;
76 private int mColor;
77 private int mStyle;
78 private int mCap;
79 private int mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070080 private int mTextAlign;
Xavier Ducrohet91672792011-02-22 11:54:37 -080081 private Typeface_Delegate mTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070082 private float mStrokeWidth;
83 private float mStrokeMiter;
84 private float mTextSize;
85 private float mTextScaleX;
86 private float mTextSkewX;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -070087 private int mHintingMode = Paint.HINTING_ON;
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -070088 private int mHyphenEdit;
89 private float mLetterSpacing; // not used in actual text rendering.
Deepanshu Gupta8916b212014-06-11 15:40:47 -070090 // Variant of the font. A paint's variant can only be compact or elegant.
91 private FontVariant mFontVariant = FontVariant.COMPACT;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070092
Xavier Ducrohet91672792011-02-22 11:54:37 -080093 private Xfermode_Delegate mXfermode;
94 private ColorFilter_Delegate mColorFilter;
95 private Shader_Delegate mShader;
96 private PathEffect_Delegate mPathEffect;
97 private MaskFilter_Delegate mMaskFilter;
98 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -070099
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700100 private Locale mLocale = Locale.getDefault();
101
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700102 // Used only to assert invariants.
103 public long mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700104
105 // ---- Public Helper methods ----
106
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -0700107 @Nullable
Narayan Kamath633d6882014-01-27 14:24:16 +0000108 public static Paint_Delegate getDelegate(long native_paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700109 return sManager.getDelegate(native_paint);
110 }
111
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700112 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700113 * Returns the list of {@link Font} objects.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700114 */
115 public List<FontInfo> getFonts() {
116 return mFonts;
117 }
118
Xavier Ducroheta313b652010-11-01 18:45:20 -0700119 public boolean isAntiAliased() {
120 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
121 }
122
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700123 public boolean isFilterBitmap() {
124 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
125 }
126
127 public int getStyle() {
128 return mStyle;
129 }
130
131 public int getColor() {
132 return mColor;
133 }
134
Xavier Ducrohet66225222010-12-21 01:33:04 -0800135 public int getAlpha() {
136 return mColor >>> 24;
137 }
138
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800139 public void setAlpha(int alpha) {
140 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
141 }
142
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700143 public int getTextAlign() {
144 return mTextAlign;
145 }
146
147 public float getStrokeWidth() {
148 return mStrokeWidth;
149 }
150
Xavier Ducrohet66225222010-12-21 01:33:04 -0800151 /**
152 * returns the value of stroke miter needed by the java api.
153 */
154 public float getJavaStrokeMiter() {
Diego Pereza1c60152015-12-18 16:01:24 +0000155 return mStrokeMiter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700156 }
157
158 public int getJavaCap() {
159 switch (Paint.sCapArray[mCap]) {
160 case BUTT:
161 return BasicStroke.CAP_BUTT;
162 case ROUND:
163 return BasicStroke.CAP_ROUND;
164 default:
165 case SQUARE:
166 return BasicStroke.CAP_SQUARE;
167 }
168 }
169
170 public int getJavaJoin() {
171 switch (Paint.sJoinArray[mJoin]) {
172 default:
173 case MITER:
174 return BasicStroke.JOIN_MITER;
175 case ROUND:
176 return BasicStroke.JOIN_ROUND;
177 case BEVEL:
178 return BasicStroke.JOIN_BEVEL;
179 }
180 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700181
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800182 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800183 if (mPathEffect != null) {
184 if (mPathEffect.isSupported()) {
185 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800186 assert stroke != null;
187 if (stroke != null) {
188 return stroke;
189 }
190 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800191 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800192 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800193 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800194 }
195 }
196
197 // if no custom stroke as been set, set the default one.
198 return new BasicStroke(
199 getStrokeWidth(),
200 getJavaCap(),
201 getJavaJoin(),
202 getJavaStrokeMiter());
203 }
204
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800205 /**
206 * Returns the {@link Xfermode} delegate or null if none have been set
207 *
208 * @return the delegate or null.
209 */
210 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800211 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700212 }
213
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800214 /**
215 * Returns the {@link ColorFilter} delegate or null if none have been set
216 *
217 * @return the delegate or null.
218 */
219 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800220 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700221 }
222
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800223 /**
224 * Returns the {@link Shader} delegate or null if none have been set
225 *
226 * @return the delegate or null.
227 */
228 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800229 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700230 }
231
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800232 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800233 * Returns the {@link MaskFilter} delegate or null if none have been set
234 *
235 * @return the delegate or null.
236 */
237 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800238 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800239 }
240
241 /**
242 * Returns the {@link Rasterizer} delegate or null if none have been set
243 *
244 * @return the delegate or null.
245 */
246 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800247 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700248 }
249
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700250 // ---- native methods ----
251
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800252 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700253 /*package*/ static int getFlags(Paint thisPaint) {
254 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400255 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700256 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700257 return 0;
258 }
259
260 return delegate.mFlags;
261 }
262
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700263
264
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800265 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700266 /*package*/ static void setFlags(Paint thisPaint, int flags) {
267 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400268 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700269 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700270 return;
271 }
272
273 delegate.mFlags = flags;
274 }
275
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800276 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700277 /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700278 setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700279 }
280
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800281 @LayoutlibDelegate
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700282 /*package*/ static int getHinting(Paint thisPaint) {
283 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400284 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700285 if (delegate == null) {
286 return Paint.HINTING_ON;
287 }
288
289 return delegate.mHintingMode;
290 }
291
292 @LayoutlibDelegate
293 /*package*/ static void setHinting(Paint thisPaint, int mode) {
294 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400295 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700296 if (delegate == null) {
297 return;
298 }
299
300 delegate.mHintingMode = mode;
301 }
302
303 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700304 /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
305 setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
306 }
307
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800308 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700309 /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
310 setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
311 }
312
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800313 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700314 /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
315 setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
316 }
317
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800318 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700319 /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
320 setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
321 }
322
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800323 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700324 /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
325 setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
326 }
327
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800328 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700329 /*package*/ static void setDither(Paint thisPaint, boolean dither) {
330 setFlag(thisPaint, Paint.DITHER_FLAG, dither);
331 }
332
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800333 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700334 /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
335 setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
336 }
337
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800338 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700339 /*package*/ static int getColor(Paint thisPaint) {
340 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400341 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700342 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700343 return 0;
344 }
345
346 return delegate.mColor;
347 }
348
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800349 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700350 /*package*/ static void setColor(Paint thisPaint, int color) {
351 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400352 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700353 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700354 return;
355 }
356
357 delegate.mColor = color;
358 }
359
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800360 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700361 /*package*/ static int getAlpha(Paint thisPaint) {
362 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400363 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700364 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700365 return 0;
366 }
367
Xavier Ducrohet66225222010-12-21 01:33:04 -0800368 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700369 }
370
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800371 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700372 /*package*/ static void setAlpha(Paint thisPaint, int a) {
373 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400374 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700375 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700376 return;
377 }
378
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800379 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 }
381
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800382 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700383 /*package*/ static float getStrokeWidth(Paint thisPaint) {
384 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400385 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700386 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700387 return 1.f;
388 }
389
390 return delegate.mStrokeWidth;
391 }
392
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800393 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700394 /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
395 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400396 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700397 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700398 return;
399 }
400
401 delegate.mStrokeWidth = width;
402 }
403
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800404 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700405 /*package*/ static float getStrokeMiter(Paint thisPaint) {
406 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400407 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700408 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700409 return 1.f;
410 }
411
412 return delegate.mStrokeMiter;
413 }
414
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800415 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700416 /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
417 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400418 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700419 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700420 return;
421 }
422
423 delegate.mStrokeMiter = miter;
424 }
425
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800426 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700427 /*package*/ static void native_setShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700428 int color) {
429 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800430 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800431 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700432 }
433
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800434 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700435 /*package*/ static boolean native_hasShadowLayer(long paint) {
436 // FIXME
437 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
438 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
439 return false;
440 }
441
442 @LayoutlibDelegate
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700443 /*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700444 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400445 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700446 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700447 }
448
449 @LayoutlibDelegate
450 /*package*/ static void setElegantTextHeight(Paint thisPaint, boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700451 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400452 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700453 if (delegate == null) {
454 return;
455 }
456
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700457 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700458 }
459
460 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700461 /*package*/ static float getTextSize(Paint thisPaint) {
462 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400463 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700464 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700465 return 1.f;
466 }
467
468 return delegate.mTextSize;
469 }
470
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800471 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700472 /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
473 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400474 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700475 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700476 return;
477 }
478
Diego Perezcdf4dc02015-09-24 14:52:59 +0100479 if (delegate.mTextSize != textSize) {
480 delegate.mTextSize = textSize;
481 delegate.updateFontObject();
482 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700483 }
484
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800485 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700486 /*package*/ static float getTextScaleX(Paint thisPaint) {
487 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400488 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700489 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700490 return 1.f;
491 }
492
493 return delegate.mTextScaleX;
494 }
495
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800496 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700497 /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
498 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400499 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700500 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700501 return;
502 }
503
Diego Perezcdf4dc02015-09-24 14:52:59 +0100504 if (delegate.mTextScaleX != scaleX) {
505 delegate.mTextScaleX = scaleX;
506 delegate.updateFontObject();
507 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700508 }
509
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800510 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700511 /*package*/ static float getTextSkewX(Paint thisPaint) {
512 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400513 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700514 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700515 return 1.f;
516 }
517
518 return delegate.mTextSkewX;
519 }
520
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800521 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700522 /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
523 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400524 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700525 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700526 return;
527 }
528
Diego Perezcdf4dc02015-09-24 14:52:59 +0100529 if (delegate.mTextSkewX != skewX) {
530 delegate.mTextSkewX = skewX;
531 delegate.updateFontObject();
532 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700533 }
534
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800535 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700536 /*package*/ static float ascent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800537 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400538 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800539 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800540 return 0;
541 }
542
543 if (delegate.mFonts.size() > 0) {
544 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
545 // Android expects negative ascent so we invert the value from Java.
546 return - javaMetrics.getAscent();
547 }
548
549 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700550 }
551
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800552 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700553 /*package*/ static float descent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800554 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400555 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800556 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800557 return 0;
558 }
559
560 if (delegate.mFonts.size() > 0) {
561 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
562 return javaMetrics.getDescent();
563 }
564
565 return 0;
566
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700567 }
568
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800569 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700570 /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700571 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400572 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700573 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700574 return 0;
575 }
576
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800577 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700578 }
579
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800580 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700581 /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700582 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400583 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700584 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700585 return 0;
586 }
587
588 if (delegate.mFonts.size() > 0) {
589 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
590 if (fmi != null) {
591 // Android expects negative ascent so we invert the value from Java.
592 fmi.top = - javaMetrics.getMaxAscent();
593 fmi.ascent = - javaMetrics.getAscent();
594 fmi.descent = javaMetrics.getDescent();
595 fmi.bottom = javaMetrics.getMaxDescent();
596 fmi.leading = javaMetrics.getLeading();
597 }
598
599 return javaMetrics.getHeight();
600 }
601
602 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700603 }
604
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800605 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700606 /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700607 int count, int bidiFlags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700608 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400609 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700610 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700611 return 0;
612 }
613
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700614 RectF bounds = delegate.measureText(text, index, count, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800615 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700616 }
617
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800618 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700619 /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end,
620 int bidiFlags) {
621 return native_measureText(thisPaint, text.toCharArray(), start, end - start, bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700622 }
623
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800624 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700625 /*package*/ static float native_measureText(Paint thisPaint, String text, int bidiFlags) {
626 return native_measureText(thisPaint, text.toCharArray(), 0, text.length(), bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700627 }
628
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800629 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700630 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, char[] text,
631 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800632
633 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700634 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800635 if (delegate == null) {
636 return 0;
637 }
638
639 int inc = count > 0 ? 1 : -1;
640
641 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800642 for (int i = index; i != index + count; i += inc, measureIndex++) {
643 int start, end;
644 if (i < index) {
645 start = i;
646 end = index;
647 } else {
648 start = index;
649 end = i;
650 }
651
652 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700653 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800654 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800655
656 if (measuredWidth != null) {
657 measuredWidth[measureIndex] = res;
658 }
659
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800660 if (res > maxWidth) {
661 // we should not return this char index, but since it's 0-based
662 // and we need to return a count, we simply return measureIndex;
663 return measureIndex;
664 }
665
666 }
667
668 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700669 }
670
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800671 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700672 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, String text,
673 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700674 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700675 return native_breakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
676 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700677 }
678
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800679 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000680 /*package*/ static long native_init() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700681 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800682 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700683 }
684
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800685 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000686 /*package*/ static long native_initWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700687 // get the delegate from the native int.
688 Paint_Delegate delegate = sManager.getDelegate(paint);
689 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700690 return 0;
691 }
692
693 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800694 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700695 }
696
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800697 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000698 /*package*/ static void native_reset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700699 // get the delegate from the native int.
700 Paint_Delegate delegate = sManager.getDelegate(native_object);
701 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700702 return;
703 }
704
705 delegate.reset();
706 }
707
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800708 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000709 /*package*/ static void native_set(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700710 // get the delegate from the native int.
711 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
712 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700713 return;
714 }
715
716 // get the delegate from the native int.
717 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
718 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700719 return;
720 }
721
722 delegate_dst.set(delegate_src);
723 }
724
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800725 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800726 /*package*/ static int native_getStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700727 // get the delegate from the native int.
728 Paint_Delegate delegate = sManager.getDelegate(native_object);
729 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700730 return 0;
731 }
732
733 return delegate.mStyle;
734 }
735
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800736 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000737 /*package*/ static void native_setStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700738 // get the delegate from the native int.
739 Paint_Delegate delegate = sManager.getDelegate(native_object);
740 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700741 return;
742 }
743
744 delegate.mStyle = style;
745 }
746
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800747 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800748 /*package*/ static int native_getStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700749 // get the delegate from the native int.
750 Paint_Delegate delegate = sManager.getDelegate(native_object);
751 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700752 return 0;
753 }
754
755 return delegate.mCap;
756 }
757
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800758 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000759 /*package*/ static void native_setStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700760 // get the delegate from the native int.
761 Paint_Delegate delegate = sManager.getDelegate(native_object);
762 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700763 return;
764 }
765
766 delegate.mCap = cap;
767 }
768
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800769 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800770 /*package*/ static int native_getStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700771 // get the delegate from the native int.
772 Paint_Delegate delegate = sManager.getDelegate(native_object);
773 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700774 return 0;
775 }
776
777 return delegate.mJoin;
778 }
779
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800780 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000781 /*package*/ static void native_setStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700782 // get the delegate from the native int.
783 Paint_Delegate delegate = sManager.getDelegate(native_object);
784 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700785 return;
786 }
787
788 delegate.mJoin = join;
789 }
790
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800791 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000792 /*package*/ static boolean native_getFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800793 Paint_Delegate paint = sManager.getDelegate(native_object);
794 if (paint == null) {
795 return false;
796 }
797
798 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
799 if (srcPath == null) {
800 return true;
801 }
802
803 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
804 if (dstPath == null) {
805 return true;
806 }
807
808 Stroke stroke = paint.getJavaStroke();
809 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
810
811 dstPath.setJavaShape(strokeShape);
812
813 // FIXME figure out the return value?
814 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700815 }
816
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800817 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000818 /*package*/ static long native_setShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700819 // get the delegate from the native int.
820 Paint_Delegate delegate = sManager.getDelegate(native_object);
821 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700822 return shader;
823 }
824
Xavier Ducrohet91672792011-02-22 11:54:37 -0800825 delegate.mShader = Shader_Delegate.getDelegate(shader);
826
827 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700828 }
829
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800830 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000831 /*package*/ static long native_setColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700832 // get the delegate from the native int.
833 Paint_Delegate delegate = sManager.getDelegate(native_object);
834 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700835 return filter;
836 }
837
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700838 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800839
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700840 // Log warning if it's not supported.
841 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800842 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800843 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800844 }
845
846 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700847 }
848
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800849 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000850 /*package*/ static long native_setXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700851 // get the delegate from the native int.
852 Paint_Delegate delegate = sManager.getDelegate(native_object);
853 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700854 return xfermode;
855 }
856
Xavier Ducrohet91672792011-02-22 11:54:37 -0800857 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
858
859 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700860 }
861
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800862 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000863 /*package*/ static long native_setPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700864 // get the delegate from the native int.
865 Paint_Delegate delegate = sManager.getDelegate(native_object);
866 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700867 return effect;
868 }
869
Xavier Ducrohet91672792011-02-22 11:54:37 -0800870 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
871
872 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700873 }
874
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800875 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000876 /*package*/ static long native_setMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700877 // get the delegate from the native int.
878 Paint_Delegate delegate = sManager.getDelegate(native_object);
879 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700880 return maskfilter;
881 }
882
Xavier Ducrohet91672792011-02-22 11:54:37 -0800883 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800884
885 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700886 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800887 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800888 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800889 }
890
891 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700892 }
893
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800894 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000895 /*package*/ static long native_setTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700896 // get the delegate from the native int.
897 Paint_Delegate delegate = sManager.getDelegate(native_object);
898 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700899 return 0;
900 }
901
Diego Perezcdf4dc02015-09-24 14:52:59 +0100902 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
903 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
904 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
905 delegate.mNativeTypeface = typeface;
906 delegate.updateFontObject();
907 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800908 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700909 }
910
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800911 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000912 /*package*/ static long native_setRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800913 // get the delegate from the native int.
914 Paint_Delegate delegate = sManager.getDelegate(native_object);
915 if (delegate == null) {
916 return rasterizer;
917 }
918
Xavier Ducrohet91672792011-02-22 11:54:37 -0800919 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800920
921 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700922 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800923 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800924 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800925 }
926
927 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700928 }
929
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800930 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800931 /*package*/ static int native_getTextAlign(long native_object) {
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 0;
936 }
937
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700938 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700939 }
940
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800941 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000942 /*package*/ static void native_setTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700943 // get the delegate from the native int.
944 Paint_Delegate delegate = sManager.getDelegate(native_object);
945 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700946 return;
947 }
948
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700949 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700950 }
951
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800952 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000953 /*package*/ static void native_setTextLocale(long native_object, String locale) {
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700954 // get the delegate from the native int.
955 Paint_Delegate delegate = sManager.getDelegate(native_object);
956 if (delegate == null) {
957 return;
958 }
959
960 delegate.setTextLocale(locale);
961 }
962
963 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700964 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
965 char[] text, int index, int count, int bidiFlags, float[] widths) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700966
967 if (widths != null) {
968 for (int i = 0; i< count; i++) {
969 widths[i]=0;
970 }
971 }
972 // get the delegate from the native int.
973 Paint_Delegate delegate = sManager.getDelegate(native_object);
974 if (delegate == null) {
975 return 0;
976 }
977
978 // native_typeface is passed here since Framework's old implementation did not have the
979 // typeface object associated with the Paint. Since, we follow the new framework way,
980 // we store the typeface with the paint and use it directly.
981 assert (native_typeface == delegate.mNativeTypeface);
982
983 RectF bounds = delegate.measureText(text, index, count, widths, 0, bidiFlags);
984 return ((int) (bounds.right - bounds.left));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700985 }
986
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800987 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700988 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
989 String text, int start, int end, int bidiFlags, float[] widths) {
990 return native_getTextWidths(native_object, native_typeface, text.toCharArray(), start,
991 end - start, bidiFlags, widths);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700992 }
993
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800994 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800995 /* package */static int native_getTextGlyphs(long native_object, String text, int start,
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700996 int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
997 // FIXME
998 return 0;
999 }
1000
1001 @LayoutlibDelegate
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001002 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001003 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001004 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001005
1006 if (advances != null)
1007 for (int i = advancesIndex; i< advancesIndex+count; i++)
1008 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001009 // get the delegate from the native int.
1010 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001011 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001012 return 0.f;
1013 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001014
1015 // native_typeface is passed here since Framework's old implementation did not have the
1016 // typeface object associated with the Paint. Since, we follow the new framework way,
1017 // we store the typeface with the paint and use it directly.
1018 assert (native_typeface == delegate.mNativeTypeface);
1019
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001020 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, isRtl);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -08001021 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001022 }
1023
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001024 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001025 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001026 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001027 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001028 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001029 int count = end - start;
1030 char[] buffer = TemporaryBuffer.obtain(count);
1031 TextUtils.getChars(text, start, end, buffer, 0);
1032
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001033 return native_getTextRunAdvances(native_object, native_typeface, buffer, 0, count,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001034 contextStart, contextEnd - contextStart, isRtl, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001035 }
1036
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001037 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001038 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001039 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
1040 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001041 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1042 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1043 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001044 }
1045
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001046 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001047 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001048 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1049 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001050 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1051 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1052 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001053 }
1054
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001055 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001056 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1057 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001058 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001059 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1060 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001061 }
1062
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001063 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001064 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1065 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001066 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001067 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1068 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001069 }
1070
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001071 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001072 /*package*/ static void nativeGetStringBounds(long nativePaint, long native_typeface,
1073 String text, int start, int end, int bidiFlags, Rect bounds) {
1074 nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
1075 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001076 }
1077
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001078 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001079 /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
1080 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001081
1082 // get the delegate from the native int.
1083 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001084 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001085 return;
1086 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001087
1088 // assert that the typeface passed is actually the one that we had stored.
1089 assert (native_typeface == delegate.mNativeTypeface);
1090
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001091 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001092 }
1093
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001094 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +00001095 /*package*/ static void finalizer(long nativePaint) {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001096 sManager.removeJavaReferenceFor(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001097 }
1098
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001099 @LayoutlibDelegate
1100 /*package*/ static float native_getLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001101 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1102 if (delegate == null) {
1103 return 0;
1104 }
1105 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001106 }
1107
1108 @LayoutlibDelegate
1109 /*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001110 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1111 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001112 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1113 if (delegate == null) {
1114 return;
1115 }
1116 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001117 }
1118
1119 @LayoutlibDelegate
1120 /*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001121 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001122 "Paint.setFontFeatureSettings() not supported.", null, null);
1123 }
1124
1125 @LayoutlibDelegate
1126 /*package*/ static int native_getHyphenEdit(long nativePaint) {
1127 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1128 if (delegate == null) {
1129 return 0;
1130 }
1131 return delegate.mHyphenEdit;
1132 }
1133
1134 @LayoutlibDelegate
1135 /*package*/ static void native_setHyphenEdit(long nativePaint, int hyphen) {
1136 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1137 if (delegate == null) {
1138 return;
1139 }
1140 delegate.mHyphenEdit = hyphen;
1141 }
1142
1143 @LayoutlibDelegate
1144 /*package*/ static boolean native_hasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
1145 String string) {
1146 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1147 if (delegate == null) {
1148 return false;
1149 }
1150 if (string.length() == 0) {
1151 return false;
1152 }
1153 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001154 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001155 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1156 return false;
1157 }
1158 assert nativeTypeface == delegate.mNativeTypeface;
1159 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1160
1161 char c = string.charAt(0);
1162 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1163 if (font.canDisplay(c)) {
1164 return true;
1165 }
1166 }
1167 return false;
1168 }
1169
1170
1171 @LayoutlibDelegate
1172 /*package*/ static float native_getRunAdvance(long nativePaint, long nativeTypeface,
1173 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1174 boolean isRtl, int offset) {
1175 int count = end - start;
1176 float[] advances = new float[count];
1177 native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
1178 contextStart, contextEnd - contextStart, isRtl, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001179 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001180 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001181 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001182 sum += advances[i];
1183 }
1184 return sum;
1185 }
1186
1187 @LayoutlibDelegate
1188 /*package*/ static int native_getOffsetForAdvance(long nativePaint, long nativeTypeface,
1189 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1190 float advance) {
1191 int count = end - start;
1192 float[] advances = new float[count];
1193 native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
1194 contextStart, contextEnd - contextStart, isRtl, advances, 0);
1195 float sum = 0;
1196 int i;
1197 for (i = 0; i < count && sum < advance; i++) {
1198 sum += advances[i];
1199 }
1200 float distanceToI = sum - advance;
1201 float distanceToIMinus1 = advance - (sum - advances[i]);
1202 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001203 }
1204
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001205 // ---- Private delegate/helper methods ----
1206
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001207 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001208 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001209 }
1210
1211 private Paint_Delegate(Paint_Delegate paint) {
1212 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001213 }
1214
1215 private void set(Paint_Delegate paint) {
1216 mFlags = paint.mFlags;
1217 mColor = paint.mColor;
1218 mStyle = paint.mStyle;
1219 mCap = paint.mCap;
1220 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001221 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001222
1223 boolean needsFontUpdate = false;
1224 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1225 mTypeface = paint.mTypeface;
1226 mNativeTypeface = paint.mNativeTypeface;
1227 needsFontUpdate = true;
1228 }
1229
1230 if (mTextSize != paint.mTextSize) {
1231 mTextSize = paint.mTextSize;
1232 needsFontUpdate = true;
1233 }
1234
1235 if (mTextScaleX != paint.mTextScaleX) {
1236 mTextScaleX = paint.mTextScaleX;
1237 needsFontUpdate = true;
1238 }
1239
1240 if (mTextSkewX != paint.mTextSkewX) {
1241 mTextSkewX = paint.mTextSkewX;
1242 needsFontUpdate = true;
1243 }
1244
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001245 mStrokeWidth = paint.mStrokeWidth;
1246 mStrokeMiter = paint.mStrokeMiter;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001247 mXfermode = paint.mXfermode;
1248 mColorFilter = paint.mColorFilter;
1249 mShader = paint.mShader;
1250 mPathEffect = paint.mPathEffect;
1251 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001252 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001253 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001254
1255 if (needsFontUpdate) {
1256 updateFontObject();
1257 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001258 }
1259
1260 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001261 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001262 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001263 mStyle = Paint.Style.FILL.nativeInt;
1264 mCap = Paint.Cap.BUTT.nativeInt;
1265 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001266 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001267 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001268 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001269 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001270 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001271 mTextSize = 20.f;
1272 mTextScaleX = 1.f;
1273 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001274 mXfermode = null;
1275 mColorFilter = null;
1276 mShader = null;
1277 mPathEffect = null;
1278 mMaskFilter = null;
1279 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001280 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001281 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001282 }
1283
1284 /**
1285 * Update the {@link Font} object from the typeface, text size and scaling
1286 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001287 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001288 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001289 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001290 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001291 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001292
Diego Perezcdf4dc02015-09-24 14:52:59 +01001293 if (fonts.isEmpty()) {
1294 mFonts = Collections.emptyList();
1295 return;
1296 }
1297
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001298 // create new font objects as well as FontMetrics, based on the current text size
1299 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001300 int nFonts = fonts.size();
1301 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1302 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1303 for (int i = 0; i < nFonts; i++) {
1304 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001305 if (font == null) {
1306 // If the font is null, add null to infoList. When rendering the text, if this
1307 // null is reached, a warning will be logged.
1308 infoList.add(null);
1309 continue;
1310 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001311 FontInfo info = new FontInfo();
1312 info.mFont = font.deriveFont(mTextSize);
1313 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1314 // TODO: support skew
1315 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001316 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001317 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001318 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001319 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1320
1321 infoList.add(info);
1322 }
1323
1324 mFonts = Collections.unmodifiableList(infoList);
1325 }
1326 }
1327
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001328 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1329 int advancesIndex, int bidiFlags) {
1330 return new BidiRenderer(null, this, text)
1331 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1332 }
1333
1334 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1335 int advancesIndex, boolean isRtl) {
1336 return new BidiRenderer(null, this, text)
1337 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001338 }
1339
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001340 private float getFontMetrics(FontMetrics metrics) {
1341 if (mFonts.size() > 0) {
1342 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1343 if (metrics != null) {
1344 // Android expects negative ascent so we invert the value from Java.
1345 metrics.top = - javaMetrics.getMaxAscent();
1346 metrics.ascent = - javaMetrics.getAscent();
1347 metrics.descent = javaMetrics.getDescent();
1348 metrics.bottom = javaMetrics.getMaxDescent();
1349 metrics.leading = javaMetrics.getLeading();
1350 }
1351
1352 return javaMetrics.getHeight();
1353 }
1354
1355 return 0;
1356 }
1357
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001358 private void setTextLocale(String locale) {
1359 mLocale = new Locale(locale);
1360 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001361
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001362 private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
1363 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -04001364 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001365 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001366 return;
1367 }
1368
1369 if (flagValue) {
1370 delegate.mFlags |= flagMask;
1371 } else {
1372 delegate.mFlags &= ~flagMask;
1373 }
1374 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001375}