blob: a545283ea0ca030e460399dd7a535250a0338d5f [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() {
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800155 float miter = mStrokeMiter * mStrokeWidth;
156 if (miter < 1.f) {
157 miter = 1.f;
158 }
159 return miter;
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 /**
210 * Returns the {@link Xfermode} delegate or null if none have been set
211 *
212 * @return the delegate or null.
213 */
214 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800215 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700216 }
217
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800218 /**
219 * Returns the {@link ColorFilter} delegate or null if none have been set
220 *
221 * @return the delegate or null.
222 */
223 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800224 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700225 }
226
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800227 /**
228 * Returns the {@link Shader} delegate or null if none have been set
229 *
230 * @return the delegate or null.
231 */
232 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800233 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700234 }
235
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800236 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800237 * Returns the {@link MaskFilter} delegate or null if none have been set
238 *
239 * @return the delegate or null.
240 */
241 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800242 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800243 }
244
245 /**
246 * Returns the {@link Rasterizer} delegate or null if none have been set
247 *
248 * @return the delegate or null.
249 */
250 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800251 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700252 }
253
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700254 // ---- native methods ----
255
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800256 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700257 /*package*/ static int getFlags(Paint thisPaint) {
258 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400259 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700260 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700261 return 0;
262 }
263
264 return delegate.mFlags;
265 }
266
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700267
268
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800269 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700270 /*package*/ static void setFlags(Paint thisPaint, int flags) {
271 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400272 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700273 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700274 return;
275 }
276
277 delegate.mFlags = flags;
278 }
279
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800280 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700281 /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700282 setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700283 }
284
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800285 @LayoutlibDelegate
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700286 /*package*/ static int getHinting(Paint thisPaint) {
287 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400288 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700289 if (delegate == null) {
290 return Paint.HINTING_ON;
291 }
292
293 return delegate.mHintingMode;
294 }
295
296 @LayoutlibDelegate
297 /*package*/ static void setHinting(Paint thisPaint, int mode) {
298 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400299 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700300 if (delegate == null) {
301 return;
302 }
303
304 delegate.mHintingMode = mode;
305 }
306
307 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700308 /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
309 setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
310 }
311
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800312 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700313 /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
314 setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
315 }
316
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800317 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700318 /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
319 setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
320 }
321
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800322 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700323 /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
324 setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
325 }
326
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800327 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700328 /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
329 setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
330 }
331
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800332 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700333 /*package*/ static void setDither(Paint thisPaint, boolean dither) {
334 setFlag(thisPaint, Paint.DITHER_FLAG, dither);
335 }
336
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800337 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700338 /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
339 setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
340 }
341
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800342 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700343 /*package*/ static int getColor(Paint thisPaint) {
344 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400345 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700346 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700347 return 0;
348 }
349
350 return delegate.mColor;
351 }
352
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800353 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700354 /*package*/ static void setColor(Paint thisPaint, int color) {
355 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400356 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700357 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700358 return;
359 }
360
361 delegate.mColor = color;
362 }
363
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800364 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700365 /*package*/ static int getAlpha(Paint thisPaint) {
366 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400367 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700368 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700369 return 0;
370 }
371
Xavier Ducrohet66225222010-12-21 01:33:04 -0800372 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700373 }
374
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800375 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700376 /*package*/ static void setAlpha(Paint thisPaint, int a) {
377 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400378 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700379 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 return;
381 }
382
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800383 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700384 }
385
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800386 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700387 /*package*/ static float getStrokeWidth(Paint thisPaint) {
388 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400389 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700390 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700391 return 1.f;
392 }
393
394 return delegate.mStrokeWidth;
395 }
396
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800397 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700398 /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
399 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400400 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700401 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700402 return;
403 }
404
405 delegate.mStrokeWidth = width;
406 }
407
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800408 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700409 /*package*/ static float getStrokeMiter(Paint thisPaint) {
410 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400411 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700412 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700413 return 1.f;
414 }
415
416 return delegate.mStrokeMiter;
417 }
418
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800419 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700420 /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
421 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400422 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700423 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700424 return;
425 }
426
427 delegate.mStrokeMiter = miter;
428 }
429
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800430 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700431 /*package*/ static void native_setShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700432 int color) {
433 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800434 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800435 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700436 }
437
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800438 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700439 /*package*/ static boolean native_hasShadowLayer(long paint) {
440 // FIXME
441 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
442 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
443 return false;
444 }
445
446 @LayoutlibDelegate
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700447 /*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700448 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400449 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700450 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700451 }
452
453 @LayoutlibDelegate
454 /*package*/ static void setElegantTextHeight(Paint thisPaint, boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700455 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400456 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700457 if (delegate == null) {
458 return;
459 }
460
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700461 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700462 }
463
464 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700465 /*package*/ static float getTextSize(Paint thisPaint) {
466 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400467 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700468 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700469 return 1.f;
470 }
471
472 return delegate.mTextSize;
473 }
474
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800475 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700476 /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
477 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400478 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700479 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700480 return;
481 }
482
Diego Perezcdf4dc02015-09-24 14:52:59 +0100483 if (delegate.mTextSize != textSize) {
484 delegate.mTextSize = textSize;
485 delegate.updateFontObject();
486 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700487 }
488
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800489 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700490 /*package*/ static float getTextScaleX(Paint thisPaint) {
491 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400492 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700493 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700494 return 1.f;
495 }
496
497 return delegate.mTextScaleX;
498 }
499
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800500 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700501 /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
502 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400503 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700504 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700505 return;
506 }
507
Diego Perezcdf4dc02015-09-24 14:52:59 +0100508 if (delegate.mTextScaleX != scaleX) {
509 delegate.mTextScaleX = scaleX;
510 delegate.updateFontObject();
511 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700512 }
513
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800514 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700515 /*package*/ static float getTextSkewX(Paint thisPaint) {
516 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400517 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700518 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700519 return 1.f;
520 }
521
522 return delegate.mTextSkewX;
523 }
524
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800525 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700526 /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
527 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -0400528 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700529 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700530 return;
531 }
532
Diego Perezcdf4dc02015-09-24 14:52:59 +0100533 if (delegate.mTextSkewX != skewX) {
534 delegate.mTextSkewX = skewX;
535 delegate.updateFontObject();
536 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700537 }
538
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800539 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700540 /*package*/ static float ascent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800541 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400542 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800543 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800544 return 0;
545 }
546
547 if (delegate.mFonts.size() > 0) {
548 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
549 // Android expects negative ascent so we invert the value from Java.
550 return - javaMetrics.getAscent();
551 }
552
553 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700554 }
555
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800556 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700557 /*package*/ static float descent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800558 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400559 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800560 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800561 return 0;
562 }
563
564 if (delegate.mFonts.size() > 0) {
565 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
566 return javaMetrics.getDescent();
567 }
568
569 return 0;
570
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700571 }
572
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800573 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700574 /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700575 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400576 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700577 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700578 return 0;
579 }
580
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800581 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700582 }
583
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800584 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700585 /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700586 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400587 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700588 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700589 return 0;
590 }
591
592 if (delegate.mFonts.size() > 0) {
593 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
594 if (fmi != null) {
595 // Android expects negative ascent so we invert the value from Java.
596 fmi.top = - javaMetrics.getMaxAscent();
597 fmi.ascent = - javaMetrics.getAscent();
598 fmi.descent = javaMetrics.getDescent();
599 fmi.bottom = javaMetrics.getMaxDescent();
600 fmi.leading = javaMetrics.getLeading();
601 }
602
603 return javaMetrics.getHeight();
604 }
605
606 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700607 }
608
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800609 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700610 /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700611 int count, int bidiFlags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700612 // get the delegate
Derek Sollenberger82934b52014-10-15 13:50:33 -0400613 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700614 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700615 return 0;
616 }
617
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700618 RectF bounds = delegate.measureText(text, index, count, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800619 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700620 }
621
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800622 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700623 /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end,
624 int bidiFlags) {
625 return native_measureText(thisPaint, text.toCharArray(), start, end - start, bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700626 }
627
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800628 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700629 /*package*/ static float native_measureText(Paint thisPaint, String text, int bidiFlags) {
630 return native_measureText(thisPaint, text.toCharArray(), 0, text.length(), bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700631 }
632
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800633 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700634 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, char[] text,
635 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800636
637 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700638 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800639 if (delegate == null) {
640 return 0;
641 }
642
643 int inc = count > 0 ? 1 : -1;
644
645 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800646 for (int i = index; i != index + count; i += inc, measureIndex++) {
647 int start, end;
648 if (i < index) {
649 start = i;
650 end = index;
651 } else {
652 start = index;
653 end = i;
654 }
655
656 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700657 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800658 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800659
660 if (measuredWidth != null) {
661 measuredWidth[measureIndex] = res;
662 }
663
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800664 if (res > maxWidth) {
665 // we should not return this char index, but since it's 0-based
666 // and we need to return a count, we simply return measureIndex;
667 return measureIndex;
668 }
669
670 }
671
672 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700673 }
674
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800675 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700676 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, String text,
677 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700678 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700679 return native_breakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
680 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700681 }
682
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800683 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000684 /*package*/ static long native_init() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700685 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800686 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700687 }
688
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800689 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000690 /*package*/ static long native_initWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700691 // get the delegate from the native int.
692 Paint_Delegate delegate = sManager.getDelegate(paint);
693 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700694 return 0;
695 }
696
697 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800698 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700699 }
700
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800701 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000702 /*package*/ static void native_reset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700703 // get the delegate from the native int.
704 Paint_Delegate delegate = sManager.getDelegate(native_object);
705 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700706 return;
707 }
708
709 delegate.reset();
710 }
711
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800712 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000713 /*package*/ static void native_set(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700714 // get the delegate from the native int.
715 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
716 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700717 return;
718 }
719
720 // get the delegate from the native int.
721 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
722 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700723 return;
724 }
725
726 delegate_dst.set(delegate_src);
727 }
728
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800729 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800730 /*package*/ static int native_getStyle(long native_object) {
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 0;
735 }
736
737 return delegate.mStyle;
738 }
739
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800740 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000741 /*package*/ static void native_setStyle(long native_object, int style) {
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;
746 }
747
748 delegate.mStyle = style;
749 }
750
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800751 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800752 /*package*/ static int native_getStrokeCap(long native_object) {
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 0;
757 }
758
759 return delegate.mCap;
760 }
761
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800762 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000763 /*package*/ static void native_setStrokeCap(long native_object, int cap) {
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;
768 }
769
770 delegate.mCap = cap;
771 }
772
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800773 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800774 /*package*/ static int native_getStrokeJoin(long native_object) {
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 0;
779 }
780
781 return delegate.mJoin;
782 }
783
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800784 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000785 /*package*/ static void native_setStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700786 // get the delegate from the native int.
787 Paint_Delegate delegate = sManager.getDelegate(native_object);
788 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700789 return;
790 }
791
792 delegate.mJoin = join;
793 }
794
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800795 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000796 /*package*/ static boolean native_getFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800797 Paint_Delegate paint = sManager.getDelegate(native_object);
798 if (paint == null) {
799 return false;
800 }
801
802 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
803 if (srcPath == null) {
804 return true;
805 }
806
807 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
808 if (dstPath == null) {
809 return true;
810 }
811
812 Stroke stroke = paint.getJavaStroke();
813 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
814
815 dstPath.setJavaShape(strokeShape);
816
817 // FIXME figure out the return value?
818 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700819 }
820
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800821 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000822 /*package*/ static long native_setShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700823 // get the delegate from the native int.
824 Paint_Delegate delegate = sManager.getDelegate(native_object);
825 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700826 return shader;
827 }
828
Xavier Ducrohet91672792011-02-22 11:54:37 -0800829 delegate.mShader = Shader_Delegate.getDelegate(shader);
830
831 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700832 }
833
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800834 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000835 /*package*/ static long native_setColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700836 // get the delegate from the native int.
837 Paint_Delegate delegate = sManager.getDelegate(native_object);
838 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700839 return filter;
840 }
841
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700842 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800843
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700844 // Log warning if it's not supported.
845 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800846 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800847 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800848 }
849
850 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700851 }
852
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800853 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000854 /*package*/ static long native_setXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700855 // get the delegate from the native int.
856 Paint_Delegate delegate = sManager.getDelegate(native_object);
857 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700858 return xfermode;
859 }
860
Xavier Ducrohet91672792011-02-22 11:54:37 -0800861 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
862
863 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700864 }
865
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800866 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000867 /*package*/ static long native_setPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700868 // get the delegate from the native int.
869 Paint_Delegate delegate = sManager.getDelegate(native_object);
870 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700871 return effect;
872 }
873
Xavier Ducrohet91672792011-02-22 11:54:37 -0800874 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
875
876 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700877 }
878
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800879 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000880 /*package*/ static long native_setMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700881 // get the delegate from the native int.
882 Paint_Delegate delegate = sManager.getDelegate(native_object);
883 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700884 return maskfilter;
885 }
886
Xavier Ducrohet91672792011-02-22 11:54:37 -0800887 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800888
889 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700890 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800891 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800892 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800893 }
894
895 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700896 }
897
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800898 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000899 /*package*/ static long native_setTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700900 // get the delegate from the native int.
901 Paint_Delegate delegate = sManager.getDelegate(native_object);
902 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700903 return 0;
904 }
905
Diego Perezcdf4dc02015-09-24 14:52:59 +0100906 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
907 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
908 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
909 delegate.mNativeTypeface = typeface;
910 delegate.updateFontObject();
911 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800912 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700913 }
914
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800915 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000916 /*package*/ static long native_setRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800917 // get the delegate from the native int.
918 Paint_Delegate delegate = sManager.getDelegate(native_object);
919 if (delegate == null) {
920 return rasterizer;
921 }
922
Xavier Ducrohet91672792011-02-22 11:54:37 -0800923 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800924
925 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700926 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800927 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800928 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800929 }
930
931 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700932 }
933
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800934 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800935 /*package*/ static int native_getTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700936 // get the delegate from the native int.
937 Paint_Delegate delegate = sManager.getDelegate(native_object);
938 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700939 return 0;
940 }
941
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700942 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700943 }
944
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800945 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000946 /*package*/ static void native_setTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700947 // get the delegate from the native int.
948 Paint_Delegate delegate = sManager.getDelegate(native_object);
949 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700950 return;
951 }
952
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700953 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700954 }
955
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800956 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000957 /*package*/ static void native_setTextLocale(long native_object, String locale) {
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700958 // get the delegate from the native int.
959 Paint_Delegate delegate = sManager.getDelegate(native_object);
960 if (delegate == null) {
961 return;
962 }
963
964 delegate.setTextLocale(locale);
965 }
966
967 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700968 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
969 char[] text, int index, int count, int bidiFlags, float[] widths) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700970
971 if (widths != null) {
972 for (int i = 0; i< count; i++) {
973 widths[i]=0;
974 }
975 }
976 // get the delegate from the native int.
977 Paint_Delegate delegate = sManager.getDelegate(native_object);
978 if (delegate == null) {
979 return 0;
980 }
981
982 // native_typeface is passed here since Framework's old implementation did not have the
983 // typeface object associated with the Paint. Since, we follow the new framework way,
984 // we store the typeface with the paint and use it directly.
985 assert (native_typeface == delegate.mNativeTypeface);
986
987 RectF bounds = delegate.measureText(text, index, count, widths, 0, bidiFlags);
988 return ((int) (bounds.right - bounds.left));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700989 }
990
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800991 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700992 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
993 String text, int start, int end, int bidiFlags, float[] widths) {
994 return native_getTextWidths(native_object, native_typeface, text.toCharArray(), start,
995 end - start, bidiFlags, widths);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700996 }
997
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800998 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800999 /* package */static int native_getTextGlyphs(long native_object, String text, int start,
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -07001000 int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
1001 // FIXME
1002 return 0;
1003 }
1004
1005 @LayoutlibDelegate
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001006 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001007 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001008 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001009
1010 if (advances != null)
1011 for (int i = advancesIndex; i< advancesIndex+count; i++)
1012 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001013 // get the delegate from the native int.
1014 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001015 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001016 return 0.f;
1017 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001018
1019 // native_typeface is passed here since Framework's old implementation did not have the
1020 // typeface object associated with the Paint. Since, we follow the new framework way,
1021 // we store the typeface with the paint and use it directly.
1022 assert (native_typeface == delegate.mNativeTypeface);
1023
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001024 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, isRtl);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -08001025 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001026 }
1027
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001028 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001029 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001030 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001031 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001032 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001033 int count = end - start;
1034 char[] buffer = TemporaryBuffer.obtain(count);
1035 TextUtils.getChars(text, start, end, buffer, 0);
1036
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001037 return native_getTextRunAdvances(native_object, native_typeface, buffer, 0, count,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001038 contextStart, contextEnd - contextStart, isRtl, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001039 }
1040
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001041 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001042 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001043 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
1044 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001045 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1046 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1047 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001048 }
1049
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001050 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001051 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001052 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1053 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001054 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1055 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1056 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001057 }
1058
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001059 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001060 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1061 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001062 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001063 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1064 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001065 }
1066
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001067 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001068 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1069 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001070 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001071 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1072 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001073 }
1074
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001075 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001076 /*package*/ static void nativeGetStringBounds(long nativePaint, long native_typeface,
1077 String text, int start, int end, int bidiFlags, Rect bounds) {
1078 nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
1079 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001080 }
1081
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001082 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001083 /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
1084 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001085
1086 // get the delegate from the native int.
1087 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001088 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001089 return;
1090 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001091
1092 // assert that the typeface passed is actually the one that we had stored.
1093 assert (native_typeface == delegate.mNativeTypeface);
1094
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001095 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001096 }
1097
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001098 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +00001099 /*package*/ static void finalizer(long nativePaint) {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001100 sManager.removeJavaReferenceFor(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001101 }
1102
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001103 @LayoutlibDelegate
1104 /*package*/ static float native_getLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001105 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1106 if (delegate == null) {
1107 return 0;
1108 }
1109 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001110 }
1111
1112 @LayoutlibDelegate
1113 /*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001114 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1115 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001116 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1117 if (delegate == null) {
1118 return;
1119 }
1120 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001121 }
1122
1123 @LayoutlibDelegate
1124 /*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001125 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001126 "Paint.setFontFeatureSettings() not supported.", null, null);
1127 }
1128
1129 @LayoutlibDelegate
1130 /*package*/ static int native_getHyphenEdit(long nativePaint) {
1131 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1132 if (delegate == null) {
1133 return 0;
1134 }
1135 return delegate.mHyphenEdit;
1136 }
1137
1138 @LayoutlibDelegate
1139 /*package*/ static void native_setHyphenEdit(long nativePaint, int hyphen) {
1140 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1141 if (delegate == null) {
1142 return;
1143 }
1144 delegate.mHyphenEdit = hyphen;
1145 }
1146
1147 @LayoutlibDelegate
1148 /*package*/ static boolean native_hasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
1149 String string) {
1150 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1151 if (delegate == null) {
1152 return false;
1153 }
1154 if (string.length() == 0) {
1155 return false;
1156 }
1157 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001158 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001159 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1160 return false;
1161 }
1162 assert nativeTypeface == delegate.mNativeTypeface;
1163 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1164
1165 char c = string.charAt(0);
1166 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1167 if (font.canDisplay(c)) {
1168 return true;
1169 }
1170 }
1171 return false;
1172 }
1173
1174
1175 @LayoutlibDelegate
1176 /*package*/ static float native_getRunAdvance(long nativePaint, long nativeTypeface,
1177 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1178 boolean isRtl, int offset) {
1179 int count = end - start;
1180 float[] advances = new float[count];
1181 native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
1182 contextStart, contextEnd - contextStart, isRtl, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001183 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001184 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001185 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001186 sum += advances[i];
1187 }
1188 return sum;
1189 }
1190
1191 @LayoutlibDelegate
1192 /*package*/ static int native_getOffsetForAdvance(long nativePaint, long nativeTypeface,
1193 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1194 float advance) {
1195 int count = end - start;
1196 float[] advances = new float[count];
1197 native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
1198 contextStart, contextEnd - contextStart, isRtl, advances, 0);
1199 float sum = 0;
1200 int i;
1201 for (i = 0; i < count && sum < advance; i++) {
1202 sum += advances[i];
1203 }
1204 float distanceToI = sum - advance;
1205 float distanceToIMinus1 = advance - (sum - advances[i]);
1206 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001207 }
1208
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001209 // ---- Private delegate/helper methods ----
1210
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001211 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001212 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001213 }
1214
1215 private Paint_Delegate(Paint_Delegate paint) {
1216 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001217 }
1218
1219 private void set(Paint_Delegate paint) {
1220 mFlags = paint.mFlags;
1221 mColor = paint.mColor;
1222 mStyle = paint.mStyle;
1223 mCap = paint.mCap;
1224 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001225 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001226
1227 boolean needsFontUpdate = false;
1228 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1229 mTypeface = paint.mTypeface;
1230 mNativeTypeface = paint.mNativeTypeface;
1231 needsFontUpdate = true;
1232 }
1233
1234 if (mTextSize != paint.mTextSize) {
1235 mTextSize = paint.mTextSize;
1236 needsFontUpdate = true;
1237 }
1238
1239 if (mTextScaleX != paint.mTextScaleX) {
1240 mTextScaleX = paint.mTextScaleX;
1241 needsFontUpdate = true;
1242 }
1243
1244 if (mTextSkewX != paint.mTextSkewX) {
1245 mTextSkewX = paint.mTextSkewX;
1246 needsFontUpdate = true;
1247 }
1248
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001249 mStrokeWidth = paint.mStrokeWidth;
1250 mStrokeMiter = paint.mStrokeMiter;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001251 mXfermode = paint.mXfermode;
1252 mColorFilter = paint.mColorFilter;
1253 mShader = paint.mShader;
1254 mPathEffect = paint.mPathEffect;
1255 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001256 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001257 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001258
1259 if (needsFontUpdate) {
1260 updateFontObject();
1261 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001262 }
1263
1264 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001265 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001266 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001267 mStyle = Paint.Style.FILL.nativeInt;
1268 mCap = Paint.Cap.BUTT.nativeInt;
1269 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001270 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001271 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001272 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001273 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001274 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001275 mTextSize = 20.f;
1276 mTextScaleX = 1.f;
1277 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001278 mXfermode = null;
1279 mColorFilter = null;
1280 mShader = null;
1281 mPathEffect = null;
1282 mMaskFilter = null;
1283 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001284 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001285 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001286 }
1287
1288 /**
1289 * Update the {@link Font} object from the typeface, text size and scaling
1290 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001291 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001292 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001293 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001294 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001295 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001296
Diego Perezcdf4dc02015-09-24 14:52:59 +01001297 if (fonts.isEmpty()) {
1298 mFonts = Collections.emptyList();
1299 return;
1300 }
1301
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001302 // create new font objects as well as FontMetrics, based on the current text size
1303 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001304 int nFonts = fonts.size();
1305 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1306 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1307 for (int i = 0; i < nFonts; i++) {
1308 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001309 if (font == null) {
1310 // If the font is null, add null to infoList. When rendering the text, if this
1311 // null is reached, a warning will be logged.
1312 infoList.add(null);
1313 continue;
1314 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001315 FontInfo info = new FontInfo();
1316 info.mFont = font.deriveFont(mTextSize);
1317 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1318 // TODO: support skew
1319 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001320 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001321 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001322 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001323 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1324
1325 infoList.add(info);
1326 }
1327
1328 mFonts = Collections.unmodifiableList(infoList);
1329 }
1330 }
1331
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001332 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1333 int advancesIndex, int bidiFlags) {
1334 return new BidiRenderer(null, this, text)
1335 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1336 }
1337
1338 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1339 int advancesIndex, boolean isRtl) {
1340 return new BidiRenderer(null, this, text)
1341 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001342 }
1343
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001344 private float getFontMetrics(FontMetrics metrics) {
1345 if (mFonts.size() > 0) {
1346 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1347 if (metrics != null) {
1348 // Android expects negative ascent so we invert the value from Java.
1349 metrics.top = - javaMetrics.getMaxAscent();
1350 metrics.ascent = - javaMetrics.getAscent();
1351 metrics.descent = javaMetrics.getDescent();
1352 metrics.bottom = javaMetrics.getMaxDescent();
1353 metrics.leading = javaMetrics.getLeading();
1354 }
1355
1356 return javaMetrics.getHeight();
1357 }
1358
1359 return 0;
1360 }
1361
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001362 private void setTextLocale(String locale) {
1363 mLocale = new Locale(locale);
1364 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001365
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001366 private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
1367 // get the delegate from the native int.
Derek Sollenberger82934b52014-10-15 13:50:33 -04001368 Paint_Delegate delegate = sManager.getDelegate(thisPaint.getNativeInstance());
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001369 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001370 return;
1371 }
1372
1373 if (flagValue) {
1374 delegate.mFlags |= flagMask;
1375 } else {
1376 delegate.mFlags &= ~flagMask;
1377 }
1378 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001379}