blob: 514d7852bd05c0d835a537af5d2c4feab8646687 [file] [log] [blame]
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -080019import com.android.ide.common.rendering.api.LayoutLog;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -080020import com.android.layoutlib.bridge.Bridge;
Xavier Ducrohet3bd98982010-11-09 18:25:03 -080021import com.android.layoutlib.bridge.impl.DelegateManager;
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -080022import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070023
Deepanshu Gupta442aee62015-05-22 14:11:22 -070024import android.annotation.NonNull;
25import android.annotation.Nullable;
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -070026import android.graphics.FontFamily_Delegate.FontVariant;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070027import android.graphics.Paint.FontMetrics;
28import android.graphics.Paint.FontMetricsInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070029import android.text.TextUtils;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070030
Xavier Ducrohet37f21802010-11-01 16:17:18 -070031import java.awt.BasicStroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070032import java.awt.Font;
Xavier Ducrohetb9761242010-12-23 10:22:14 -080033import java.awt.Shape;
34import java.awt.Stroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070035import java.awt.Toolkit;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070036import java.awt.geom.AffineTransform;
37import java.util.ArrayList;
38import java.util.Collections;
39import java.util.List;
Xavier Ducrohet43526ab2012-04-23 17:41:37 -070040import java.util.Locale;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070041
Deepanshu Guptafbe158f2015-10-06 17:56:37 -070042import libcore.util.NativeAllocationRegistry_Delegate;
43
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070044/**
45 * Delegate implementing the native methods of android.graphics.Paint
46 *
47 * Through the layoutlib_create tool, the original native methods of Paint have been replaced
48 * by calls to methods of the same name in this delegate class.
49 *
50 * This class behaves like the original native implementation, but in Java, keeping previously
51 * native data into its own objects and mapping them to int that are sent back and forth between
52 * it and the original Paint class.
53 *
54 * @see DelegateManager
55 *
56 */
57public class Paint_Delegate {
58
59 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -070060 * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070061 */
Xavier Ducrohet37f21802010-11-01 16:17:18 -070062 /*package*/ static final class FontInfo {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070063 Font mFont;
64 java.awt.FontMetrics mMetrics;
65 }
66
67 // ---- delegate manager ----
68 private static final DelegateManager<Paint_Delegate> sManager =
Xavier Ducrohetb2de8392011-02-23 16:51:08 -080069 new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
Deepanshu Guptafbe158f2015-10-06 17:56:37 -070070 private static long sFinalizer = -1;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070071
72 // ---- delegate helper data ----
Deepanshu Gupta382256f2014-08-09 14:14:32 -070073
74 // This list can contain null elements.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070075 private List<FontInfo> mFonts;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070076
77 // ---- delegate data ----
78 private int mFlags;
79 private int mColor;
80 private int mStyle;
81 private int mCap;
82 private int mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070083 private int mTextAlign;
Xavier Ducrohet91672792011-02-22 11:54:37 -080084 private Typeface_Delegate mTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070085 private float mStrokeWidth;
86 private float mStrokeMiter;
87 private float mTextSize;
88 private float mTextScaleX;
89 private float mTextSkewX;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -070090 private int mHintingMode = Paint.HINTING_ON;
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -070091 private int mHyphenEdit;
92 private float mLetterSpacing; // not used in actual text rendering.
Deepanshu Gupta8916b212014-06-11 15:40:47 -070093 // Variant of the font. A paint's variant can only be compact or elegant.
94 private FontVariant mFontVariant = FontVariant.COMPACT;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070095
Xavier Ducrohet91672792011-02-22 11:54:37 -080096 private Xfermode_Delegate mXfermode;
97 private ColorFilter_Delegate mColorFilter;
98 private Shader_Delegate mShader;
99 private PathEffect_Delegate mPathEffect;
100 private MaskFilter_Delegate mMaskFilter;
101 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -0700102
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700103 private Locale mLocale = Locale.getDefault();
104
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700105 // Used only to assert invariants.
106 public long mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700107
108 // ---- Public Helper methods ----
109
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -0700110 @Nullable
Narayan Kamath633d6882014-01-27 14:24:16 +0000111 public static Paint_Delegate getDelegate(long native_paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700112 return sManager.getDelegate(native_paint);
113 }
114
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700115 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700116 * Returns the list of {@link Font} objects.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700117 */
118 public List<FontInfo> getFonts() {
119 return mFonts;
120 }
121
Xavier Ducroheta313b652010-11-01 18:45:20 -0700122 public boolean isAntiAliased() {
123 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
124 }
125
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700126 public boolean isFilterBitmap() {
127 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
128 }
129
130 public int getStyle() {
131 return mStyle;
132 }
133
134 public int getColor() {
135 return mColor;
136 }
137
Xavier Ducrohet66225222010-12-21 01:33:04 -0800138 public int getAlpha() {
139 return mColor >>> 24;
140 }
141
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800142 public void setAlpha(int alpha) {
143 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
144 }
145
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700146 public int getTextAlign() {
147 return mTextAlign;
148 }
149
150 public float getStrokeWidth() {
151 return mStrokeWidth;
152 }
153
Xavier Ducrohet66225222010-12-21 01:33:04 -0800154 /**
155 * returns the value of stroke miter needed by the java api.
156 */
157 public float getJavaStrokeMiter() {
Diego Pereza1c60152015-12-18 16:01:24 +0000158 return mStrokeMiter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700159 }
160
161 public int getJavaCap() {
162 switch (Paint.sCapArray[mCap]) {
163 case BUTT:
164 return BasicStroke.CAP_BUTT;
165 case ROUND:
166 return BasicStroke.CAP_ROUND;
167 default:
168 case SQUARE:
169 return BasicStroke.CAP_SQUARE;
170 }
171 }
172
173 public int getJavaJoin() {
174 switch (Paint.sJoinArray[mJoin]) {
175 default:
176 case MITER:
177 return BasicStroke.JOIN_MITER;
178 case ROUND:
179 return BasicStroke.JOIN_ROUND;
180 case BEVEL:
181 return BasicStroke.JOIN_BEVEL;
182 }
183 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700184
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800185 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800186 if (mPathEffect != null) {
187 if (mPathEffect.isSupported()) {
188 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800189 assert stroke != null;
190 if (stroke != null) {
191 return stroke;
192 }
193 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800194 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800195 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800196 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800197 }
198 }
199
200 // if no custom stroke as been set, set the default one.
201 return new BasicStroke(
202 getStrokeWidth(),
203 getJavaCap(),
204 getJavaJoin(),
205 getJavaStrokeMiter());
206 }
207
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800208 /**
209 * Returns the {@link Xfermode} delegate or null if none have been set
210 *
211 * @return the delegate or null.
212 */
213 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800214 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700215 }
216
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800217 /**
218 * Returns the {@link ColorFilter} delegate or null if none have been set
219 *
220 * @return the delegate or null.
221 */
222 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800223 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700224 }
225
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800226 /**
227 * Returns the {@link Shader} delegate or null if none have been set
228 *
229 * @return the delegate or null.
230 */
231 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800232 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700233 }
234
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800235 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800236 * Returns the {@link MaskFilter} delegate or null if none have been set
237 *
238 * @return the delegate or null.
239 */
240 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800241 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800242 }
243
244 /**
245 * Returns the {@link Rasterizer} delegate or null if none have been set
246 *
247 * @return the delegate or null.
248 */
249 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800250 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700251 }
252
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700253 // ---- native methods ----
254
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800255 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700256 /*package*/ static int nGetFlags(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700257 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700258 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700259 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700260 return 0;
261 }
262
263 return delegate.mFlags;
264 }
265
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700266
267
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800268 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700269 /*package*/ static void nSetFlags(Paint thisPaint, long nativePaint, int flags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700270 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700271 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700272 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700273 return;
274 }
275
276 delegate.mFlags = flags;
277 }
278
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800279 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700280 /*package*/ static void nSetFilterBitmap(Paint thisPaint, long nativePaint, boolean filter) {
281 setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700282 }
283
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800284 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700285 /*package*/ static int nGetHinting(Paint thisPaint, long nativePaint) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700286 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700287 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700288 if (delegate == null) {
289 return Paint.HINTING_ON;
290 }
291
292 return delegate.mHintingMode;
293 }
294
295 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700296 /*package*/ static void nSetHinting(Paint thisPaint, long nativePaint, int mode) {
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700297 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700298 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700299 if (delegate == null) {
300 return;
301 }
302
303 delegate.mHintingMode = mode;
304 }
305
306 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700307 /*package*/ static void nSetAntiAlias(Paint thisPaint, long nativePaint, boolean aa) {
308 setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700309 }
310
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800311 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700312 /*package*/ static void nSetSubpixelText(Paint thisPaint, long nativePaint,
313 boolean subpixelText) {
314 setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700315 }
316
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800317 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700318 /*package*/ static void nSetUnderlineText(Paint thisPaint, long nativePaint,
319 boolean underlineText) {
320 setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700321 }
322
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800323 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700324 /*package*/ static void nSetStrikeThruText(Paint thisPaint, long nativePaint,
325 boolean strikeThruText) {
326 setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700327 }
328
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800329 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700330 /*package*/ static void nSetFakeBoldText(Paint thisPaint, long nativePaint,
331 boolean fakeBoldText) {
332 setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700333 }
334
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800335 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700336 /*package*/ static void nSetDither(Paint thisPaint, long nativePaint, boolean dither) {
337 setFlag(nativePaint, Paint.DITHER_FLAG, dither);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700338 }
339
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800340 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700341 /*package*/ static void nSetLinearText(Paint thisPaint, long nativePaint, boolean linearText) {
342 setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700343 }
344
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800345 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700346 /*package*/ static int nGetColor(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700347 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700348 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700349 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700350 return 0;
351 }
352
353 return delegate.mColor;
354 }
355
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800356 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700357 /*package*/ static void nSetColor(Paint thisPaint, long nativePaint, int color) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700358 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700359 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700360 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700361 return;
362 }
363
364 delegate.mColor = color;
365 }
366
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800367 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700368 /*package*/ static int nGetAlpha(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700369 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700370 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700371 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700372 return 0;
373 }
374
Xavier Ducrohet66225222010-12-21 01:33:04 -0800375 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700376 }
377
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800378 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700379 /*package*/ static void nSetAlpha(Paint thisPaint, long nativePaint, int a) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700381 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700382 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700383 return;
384 }
385
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800386 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700387 }
388
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800389 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700390 /*package*/ static float nGetStrokeWidth(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700391 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700392 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700393 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700394 return 1.f;
395 }
396
397 return delegate.mStrokeWidth;
398 }
399
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800400 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700401 /*package*/ static void nSetStrokeWidth(Paint thisPaint, long nativePaint, float width) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700402 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700403 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700404 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700405 return;
406 }
407
408 delegate.mStrokeWidth = width;
409 }
410
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800411 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700412 /*package*/ static float nGetStrokeMiter(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700413 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700414 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700415 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700416 return 1.f;
417 }
418
419 return delegate.mStrokeMiter;
420 }
421
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800422 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700423 /*package*/ static void nSetStrokeMiter(Paint thisPaint, long nativePaint, float miter) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700424 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700425 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700426 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700427 return;
428 }
429
430 delegate.mStrokeMiter = miter;
431 }
432
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800433 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700434 /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700435 int color) {
436 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800437 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800438 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700439 }
440
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800441 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700442 /*package*/ static boolean nHasShadowLayer(long paint) {
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700443 // FIXME
444 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
445 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
446 return false;
447 }
448
449 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700450 /*package*/ static boolean nIsElegantTextHeight(Paint thisPaint, long nativePaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700451 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700452 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700453 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700454 }
455
456 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700457 /*package*/ static void nSetElegantTextHeight(Paint thisPaint, long nativePaint,
458 boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700459 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700460 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700461 if (delegate == null) {
462 return;
463 }
464
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700465 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700466 }
467
468 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700469 /*package*/ static float nGetTextSize(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700470 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700471 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700472 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700473 return 1.f;
474 }
475
476 return delegate.mTextSize;
477 }
478
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800479 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700480 /*package*/ static void nSetTextSize(Paint thisPaint, long nativePaint, float textSize) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700481 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700482 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700483 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700484 return;
485 }
486
Diego Perezcdf4dc02015-09-24 14:52:59 +0100487 if (delegate.mTextSize != textSize) {
488 delegate.mTextSize = textSize;
489 delegate.updateFontObject();
490 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700491 }
492
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800493 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700494 /*package*/ static float nGetTextScaleX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700495 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700496 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700497 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700498 return 1.f;
499 }
500
501 return delegate.mTextScaleX;
502 }
503
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800504 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700505 /*package*/ static void nSetTextScaleX(Paint thisPaint, long nativePaint, float scaleX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700506 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700507 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700508 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700509 return;
510 }
511
Diego Perezcdf4dc02015-09-24 14:52:59 +0100512 if (delegate.mTextScaleX != scaleX) {
513 delegate.mTextScaleX = scaleX;
514 delegate.updateFontObject();
515 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700516 }
517
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800518 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700519 /*package*/ static float nGetTextSkewX(Paint thisPaint, long nativePaint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700520 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700521 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700522 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700523 return 1.f;
524 }
525
526 return delegate.mTextSkewX;
527 }
528
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800529 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700530 /*package*/ static void nSetTextSkewX(Paint thisPaint, long nativePaint, float skewX) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700531 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700532 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700533 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700534 return;
535 }
536
Diego Perezcdf4dc02015-09-24 14:52:59 +0100537 if (delegate.mTextSkewX != skewX) {
538 delegate.mTextSkewX = skewX;
539 delegate.updateFontObject();
540 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700541 }
542
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800543 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700544 /*package*/ static float nAscent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800545 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700546 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800547 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800548 return 0;
549 }
550
551 if (delegate.mFonts.size() > 0) {
552 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
553 // Android expects negative ascent so we invert the value from Java.
554 return - javaMetrics.getAscent();
555 }
556
557 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700558 }
559
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800560 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700561 /*package*/ static float nDescent(Paint thisPaint, long nativePaint, long nativeTypeface) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800562 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700563 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800564 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800565 return 0;
566 }
567
568 if (delegate.mFonts.size() > 0) {
569 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
570 return javaMetrics.getDescent();
571 }
572
573 return 0;
574
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700575 }
576
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800577 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700578 /*package*/ static float nGetFontMetrics(Paint thisPaint, long nativePaint, long nativeTypeface,
579 FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700580 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700581 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700582 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700583 return 0;
584 }
585
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800586 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700587 }
588
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800589 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700590 /*package*/ static int nGetFontMetricsInt(Paint thisPaint, long nativePaint,
591 long nativeTypeface, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700592 // get the delegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700593 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700594 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700595 return 0;
596 }
597
598 if (delegate.mFonts.size() > 0) {
599 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
600 if (fmi != null) {
601 // Android expects negative ascent so we invert the value from Java.
602 fmi.top = - javaMetrics.getMaxAscent();
603 fmi.ascent = - javaMetrics.getAscent();
604 fmi.descent = javaMetrics.getDescent();
605 fmi.bottom = javaMetrics.getMaxDescent();
606 fmi.leading = javaMetrics.getLeading();
607 }
608
609 return javaMetrics.getHeight();
610 }
611
612 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700613 }
614
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800615 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700616 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700617 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800618
619 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700620 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800621 if (delegate == null) {
622 return 0;
623 }
624
625 int inc = count > 0 ? 1 : -1;
626
627 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800628 for (int i = index; i != index + count; i += inc, measureIndex++) {
629 int start, end;
630 if (i < index) {
631 start = i;
632 end = index;
633 } else {
634 start = index;
635 end = i;
636 }
637
638 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700639 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800640 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800641
642 if (measuredWidth != null) {
643 measuredWidth[measureIndex] = res;
644 }
645
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800646 if (res > maxWidth) {
647 // we should not return this char index, but since it's 0-based
648 // and we need to return a count, we simply return measureIndex;
649 return measureIndex;
650 }
651
652 }
653
654 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700655 }
656
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800657 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700658 /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700659 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700660 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700661 return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700662 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700663 }
664
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800665 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700666 /*package*/ static long nInit() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700667 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800668 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700669 }
670
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800671 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700672 /*package*/ static long nInitWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700673 // get the delegate from the native int.
674 Paint_Delegate delegate = sManager.getDelegate(paint);
675 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700676 return 0;
677 }
678
679 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800680 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700681 }
682
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800683 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700684 /*package*/ static void nReset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700685 // get the delegate from the native int.
686 Paint_Delegate delegate = sManager.getDelegate(native_object);
687 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700688 return;
689 }
690
691 delegate.reset();
692 }
693
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800694 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700695 /*package*/ static void nSet(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700696 // get the delegate from the native int.
697 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
698 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700699 return;
700 }
701
702 // get the delegate from the native int.
703 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
704 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700705 return;
706 }
707
708 delegate_dst.set(delegate_src);
709 }
710
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800711 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700712 /*package*/ static int nGetStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700713 // get the delegate from the native int.
714 Paint_Delegate delegate = sManager.getDelegate(native_object);
715 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700716 return 0;
717 }
718
719 return delegate.mStyle;
720 }
721
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800722 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700723 /*package*/ static void nSetStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700724 // get the delegate from the native int.
725 Paint_Delegate delegate = sManager.getDelegate(native_object);
726 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700727 return;
728 }
729
730 delegate.mStyle = style;
731 }
732
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800733 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700734 /*package*/ static int nGetStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700735 // get the delegate from the native int.
736 Paint_Delegate delegate = sManager.getDelegate(native_object);
737 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700738 return 0;
739 }
740
741 return delegate.mCap;
742 }
743
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800744 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700745 /*package*/ static void nSetStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700746 // get the delegate from the native int.
747 Paint_Delegate delegate = sManager.getDelegate(native_object);
748 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700749 return;
750 }
751
752 delegate.mCap = cap;
753 }
754
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800755 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700756 /*package*/ static int nGetStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700757 // get the delegate from the native int.
758 Paint_Delegate delegate = sManager.getDelegate(native_object);
759 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700760 return 0;
761 }
762
763 return delegate.mJoin;
764 }
765
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800766 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700767 /*package*/ static void nSetStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700768 // get the delegate from the native int.
769 Paint_Delegate delegate = sManager.getDelegate(native_object);
770 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700771 return;
772 }
773
774 delegate.mJoin = join;
775 }
776
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800777 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700778 /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800779 Paint_Delegate paint = sManager.getDelegate(native_object);
780 if (paint == null) {
781 return false;
782 }
783
784 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
785 if (srcPath == null) {
786 return true;
787 }
788
789 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
790 if (dstPath == null) {
791 return true;
792 }
793
794 Stroke stroke = paint.getJavaStroke();
795 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
796
797 dstPath.setJavaShape(strokeShape);
798
799 // FIXME figure out the return value?
800 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700801 }
802
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800803 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700804 /*package*/ static long nSetShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700805 // get the delegate from the native int.
806 Paint_Delegate delegate = sManager.getDelegate(native_object);
807 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700808 return shader;
809 }
810
Xavier Ducrohet91672792011-02-22 11:54:37 -0800811 delegate.mShader = Shader_Delegate.getDelegate(shader);
812
813 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700814 }
815
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800816 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700817 /*package*/ static long nSetColorFilter(long native_object, long filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700818 // get the delegate from the native int.
819 Paint_Delegate delegate = sManager.getDelegate(native_object);
820 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700821 return filter;
822 }
823
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700824 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800825
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700826 // Log warning if it's not supported.
827 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800828 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800829 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800830 }
831
832 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700833 }
834
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800835 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700836 /*package*/ static long nSetXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700837 // get the delegate from the native int.
838 Paint_Delegate delegate = sManager.getDelegate(native_object);
839 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700840 return xfermode;
841 }
842
Xavier Ducrohet91672792011-02-22 11:54:37 -0800843 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
844
845 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700846 }
847
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800848 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700849 /*package*/ static long nSetPathEffect(long native_object, long effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700850 // get the delegate from the native int.
851 Paint_Delegate delegate = sManager.getDelegate(native_object);
852 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700853 return effect;
854 }
855
Xavier Ducrohet91672792011-02-22 11:54:37 -0800856 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
857
858 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700859 }
860
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800861 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700862 /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700863 // get the delegate from the native int.
864 Paint_Delegate delegate = sManager.getDelegate(native_object);
865 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700866 return maskfilter;
867 }
868
Xavier Ducrohet91672792011-02-22 11:54:37 -0800869 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800870
871 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700872 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800873 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800874 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800875 }
876
877 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700878 }
879
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800880 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700881 /*package*/ static long nSetTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700882 // get the delegate from the native int.
883 Paint_Delegate delegate = sManager.getDelegate(native_object);
884 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700885 return 0;
886 }
887
Diego Perezcdf4dc02015-09-24 14:52:59 +0100888 Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
889 if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
890 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
891 delegate.mNativeTypeface = typeface;
892 delegate.updateFontObject();
893 }
Xavier Ducrohet91672792011-02-22 11:54:37 -0800894 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700895 }
896
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800897 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700898 /*package*/ static long nSetRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800899 // get the delegate from the native int.
900 Paint_Delegate delegate = sManager.getDelegate(native_object);
901 if (delegate == null) {
902 return rasterizer;
903 }
904
Xavier Ducrohet91672792011-02-22 11:54:37 -0800905 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800906
907 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700908 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800909 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800910 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800911 }
912
913 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700914 }
915
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800916 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700917 /*package*/ static int nGetTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700918 // get the delegate from the native int.
919 Paint_Delegate delegate = sManager.getDelegate(native_object);
920 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700921 return 0;
922 }
923
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700924 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700925 }
926
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800927 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700928 /*package*/ static void nSetTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700929 // get the delegate from the native int.
930 Paint_Delegate delegate = sManager.getDelegate(native_object);
931 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700932 return;
933 }
934
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700935 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700936 }
937
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800938 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700939 /*package*/ static int nSetTextLocales(long native_object, String locale) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700940 // get the delegate from the native int.
941 Paint_Delegate delegate = sManager.getDelegate(native_object);
942 if (delegate == null) {
943 return 0;
944 }
945
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700946 delegate.setTextLocale(locale);
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700947 return 0;
948 }
949
950 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700951 /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
952 int mMinikinLangListId) {
953 // FIXME
954 }
955
956 @LayoutlibDelegate
957 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700958 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700959 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700960
961 if (advances != null)
962 for (int i = advancesIndex; i< advancesIndex+count; i++)
963 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700964 // get the delegate from the native int.
965 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700966 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700967 return 0.f;
968 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700969
970 // native_typeface is passed here since Framework's old implementation did not have the
971 // typeface object associated with the Paint. Since, we follow the new framework way,
972 // we store the typeface with the paint and use it directly.
973 assert (native_typeface == delegate.mNativeTypeface);
974
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700975 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800976 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700977 }
978
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800979 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700980 /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700981 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700982 int bidiFlags, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700983 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700984 int count = end - start;
985 char[] buffer = TemporaryBuffer.obtain(count);
986 TextUtils.getChars(text, start, end, buffer, 0);
987
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700988 return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
989 contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700990 }
991
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800992 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -0700993 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700994 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
995 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800996 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
997 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
998 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700999 }
1000
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001001 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001002 /*package*/ static int nGetTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001003 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1004 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001005 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1006 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1007 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001008 }
1009
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001010 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001011 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001012 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001013 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001014 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1015 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001016 }
1017
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001018 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001019 /*package*/ static void nGetTextPath(long native_object, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001020 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001021 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001022 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1023 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001024 }
1025
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001026 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001027 /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001028 String text, int start, int end, int bidiFlags, Rect bounds) {
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001029 nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001030 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001031 }
1032
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001033 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001034 /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001035 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001036
1037 // get the delegate from the native int.
1038 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001039 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001040 return;
1041 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001042
1043 // assert that the typeface passed is actually the one that we had stored.
1044 assert (native_typeface == delegate.mNativeTypeface);
1045
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001046 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001047 }
1048
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001049 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001050 /*package*/ static long nGetNativeFinalizer() {
1051 synchronized (Paint_Delegate.class) {
1052 if (sFinalizer == -1) {
1053 sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
1054 sManager::removeJavaReferenceFor);
1055 }
1056 }
1057 return sFinalizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001058 }
1059
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001060 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001061 /*package*/ static float nGetLetterSpacing(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001062 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1063 if (delegate == null) {
1064 return 0;
1065 }
1066 return delegate.mLetterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001067 }
1068
1069 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001070 /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001071 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
1072 "Paint.setLetterSpacing() not supported.", null, null);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001073 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1074 if (delegate == null) {
1075 return;
1076 }
1077 delegate.mLetterSpacing = letterSpacing;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001078 }
1079
1080 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001081 /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001082 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001083 "Paint.setFontFeatureSettings() not supported.", null, null);
1084 }
1085
1086 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001087 /*package*/ static int nGetHyphenEdit(long nativePaint) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001088 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1089 if (delegate == null) {
1090 return 0;
1091 }
1092 return delegate.mHyphenEdit;
1093 }
1094
1095 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001096 /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001097 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1098 if (delegate == null) {
1099 return;
1100 }
1101 delegate.mHyphenEdit = hyphen;
1102 }
1103
1104 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001105 /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001106 String string) {
1107 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
1108 if (delegate == null) {
1109 return false;
1110 }
1111 if (string.length() == 0) {
1112 return false;
1113 }
1114 if (string.length() > 1) {
Deepanshu Guptae4b3f9e2015-05-13 21:47:10 -07001115 Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001116 "Paint.hasGlyph() is not supported for ligatures.", null, null);
1117 return false;
1118 }
1119 assert nativeTypeface == delegate.mNativeTypeface;
1120 Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
1121
1122 char c = string.charAt(0);
1123 for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
1124 if (font.canDisplay(c)) {
1125 return true;
1126 }
1127 }
1128 return false;
1129 }
1130
1131
1132 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001133 /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001134 @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
1135 boolean isRtl, int offset) {
1136 int count = end - start;
1137 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001138 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1139 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1140 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001141 int startOffset = offset - start; // offset from start.
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001142 float sum = 0;
Deepanshu Gupta558943e2015-07-07 14:38:39 -07001143 for (int i = 0; i < startOffset; i++) {
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001144 sum += advances[i];
1145 }
1146 return sum;
1147 }
1148
1149 @LayoutlibDelegate
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001150 /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001151 char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
1152 float advance) {
1153 int count = end - start;
1154 float[] advances = new float[count];
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001155 int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
1156 nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
1157 contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
Deepanshu Gupta9fe7fca2015-05-12 12:01:16 -07001158 float sum = 0;
1159 int i;
1160 for (i = 0; i < count && sum < advance; i++) {
1161 sum += advances[i];
1162 }
1163 float distanceToI = sum - advance;
1164 float distanceToIMinus1 = advance - (sum - advances[i]);
1165 return distanceToI > distanceToIMinus1 ? i : i - 1;
Deepanshu Guptaa74fdf02014-07-30 20:18:48 -07001166 }
1167
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001168 // ---- Private delegate/helper methods ----
1169
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001170 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001171 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001172 }
1173
1174 private Paint_Delegate(Paint_Delegate paint) {
1175 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001176 }
1177
1178 private void set(Paint_Delegate paint) {
1179 mFlags = paint.mFlags;
1180 mColor = paint.mColor;
1181 mStyle = paint.mStyle;
1182 mCap = paint.mCap;
1183 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001184 mTextAlign = paint.mTextAlign;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001185
1186 boolean needsFontUpdate = false;
1187 if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
1188 mTypeface = paint.mTypeface;
1189 mNativeTypeface = paint.mNativeTypeface;
1190 needsFontUpdate = true;
1191 }
1192
1193 if (mTextSize != paint.mTextSize) {
1194 mTextSize = paint.mTextSize;
1195 needsFontUpdate = true;
1196 }
1197
1198 if (mTextScaleX != paint.mTextScaleX) {
1199 mTextScaleX = paint.mTextScaleX;
1200 needsFontUpdate = true;
1201 }
1202
1203 if (mTextSkewX != paint.mTextSkewX) {
1204 mTextSkewX = paint.mTextSkewX;
1205 needsFontUpdate = true;
1206 }
1207
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001208 mStrokeWidth = paint.mStrokeWidth;
1209 mStrokeMiter = paint.mStrokeMiter;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001210 mXfermode = paint.mXfermode;
1211 mColorFilter = paint.mColorFilter;
1212 mShader = paint.mShader;
1213 mPathEffect = paint.mPathEffect;
1214 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001215 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001216 mHintingMode = paint.mHintingMode;
Diego Perezcdf4dc02015-09-24 14:52:59 +01001217
1218 if (needsFontUpdate) {
1219 updateFontObject();
1220 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001221 }
1222
1223 private void reset() {
Chris Craikf2437d32015-05-13 13:09:50 -07001224 mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001225 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001226 mStyle = Paint.Style.FILL.nativeInt;
1227 mCap = Paint.Cap.BUTT.nativeInt;
1228 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001229 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001230 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001231 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001232 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001233 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001234 mTextSize = 20.f;
1235 mTextScaleX = 1.f;
1236 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001237 mXfermode = null;
1238 mColorFilter = null;
1239 mShader = null;
1240 mPathEffect = null;
1241 mMaskFilter = null;
1242 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001243 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001244 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001245 }
1246
1247 /**
1248 * Update the {@link Font} object from the typeface, text size and scaling
1249 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001250 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001251 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001252 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001253 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001254 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001255
Diego Perezcdf4dc02015-09-24 14:52:59 +01001256 if (fonts.isEmpty()) {
1257 mFonts = Collections.emptyList();
1258 return;
1259 }
1260
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001261 // create new font objects as well as FontMetrics, based on the current text size
1262 // and skew info.
Diego Perezcdf4dc02015-09-24 14:52:59 +01001263 int nFonts = fonts.size();
1264 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
1265 //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
1266 for (int i = 0; i < nFonts; i++) {
1267 Font font = fonts.get(i);
Deepanshu Gupta382256f2014-08-09 14:14:32 -07001268 if (font == null) {
1269 // If the font is null, add null to infoList. When rendering the text, if this
1270 // null is reached, a warning will be logged.
1271 infoList.add(null);
1272 continue;
1273 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001274 FontInfo info = new FontInfo();
1275 info.mFont = font.deriveFont(mTextSize);
1276 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1277 // TODO: support skew
1278 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001279 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001280 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001281 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001282 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1283
1284 infoList.add(info);
1285 }
1286
1287 mFonts = Collections.unmodifiableList(infoList);
1288 }
1289 }
1290
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001291 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1292 int advancesIndex, int bidiFlags) {
1293 return new BidiRenderer(null, this, text)
1294 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1295 }
1296
1297 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1298 int advancesIndex, boolean isRtl) {
1299 return new BidiRenderer(null, this, text)
1300 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001301 }
1302
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001303 private float getFontMetrics(FontMetrics metrics) {
1304 if (mFonts.size() > 0) {
1305 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1306 if (metrics != null) {
1307 // Android expects negative ascent so we invert the value from Java.
1308 metrics.top = - javaMetrics.getMaxAscent();
1309 metrics.ascent = - javaMetrics.getAscent();
1310 metrics.descent = javaMetrics.getDescent();
1311 metrics.bottom = javaMetrics.getMaxDescent();
1312 metrics.leading = javaMetrics.getLeading();
1313 }
1314
1315 return javaMetrics.getHeight();
1316 }
1317
1318 return 0;
1319 }
1320
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001321 private void setTextLocale(String locale) {
1322 mLocale = new Locale(locale);
1323 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001324
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001325 private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001326 // get the delegate from the native int.
Deepanshu Guptafbe158f2015-10-06 17:56:37 -07001327 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001328 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001329 return;
1330 }
1331
1332 if (flagValue) {
1333 delegate.mFlags |= flagMask;
1334 } else {
1335 delegate.mFlags &= ~flagMask;
1336 }
1337 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001338}