blob: 24ef1896feee56b9b898ba5bce25c8042f772d75 [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 Gupta5a6b3ab2014-05-30 17:43:33 -070024import android.graphics.FontFamily_Delegate.FontVariant;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070025import android.graphics.Paint.FontMetrics;
26import android.graphics.Paint.FontMetricsInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070027import android.text.TextUtils;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070028
Xavier Ducrohet37f21802010-11-01 16:17:18 -070029import java.awt.BasicStroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070030import java.awt.Font;
Xavier Ducrohetb9761242010-12-23 10:22:14 -080031import java.awt.Shape;
32import java.awt.Stroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070033import java.awt.Toolkit;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070034import java.awt.geom.AffineTransform;
35import java.util.ArrayList;
36import java.util.Collections;
37import java.util.List;
Xavier Ducrohet43526ab2012-04-23 17:41:37 -070038import java.util.Locale;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070039
40/**
41 * Delegate implementing the native methods of android.graphics.Paint
42 *
43 * Through the layoutlib_create tool, the original native methods of Paint have been replaced
44 * by calls to methods of the same name in this delegate class.
45 *
46 * This class behaves like the original native implementation, but in Java, keeping previously
47 * native data into its own objects and mapping them to int that are sent back and forth between
48 * it and the original Paint class.
49 *
50 * @see DelegateManager
51 *
52 */
53public class Paint_Delegate {
54
55 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -070056 * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070057 */
Xavier Ducrohet37f21802010-11-01 16:17:18 -070058 /*package*/ static final class FontInfo {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070059 Font mFont;
60 java.awt.FontMetrics mMetrics;
61 }
62
63 // ---- delegate manager ----
64 private static final DelegateManager<Paint_Delegate> sManager =
Xavier Ducrohetb2de8392011-02-23 16:51:08 -080065 new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070066
67 // ---- delegate helper data ----
68 private List<FontInfo> mFonts;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070069
70 // ---- delegate data ----
71 private int mFlags;
72 private int mColor;
73 private int mStyle;
74 private int mCap;
75 private int mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070076 private int mTextAlign;
Xavier Ducrohet91672792011-02-22 11:54:37 -080077 private Typeface_Delegate mTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070078 private float mStrokeWidth;
79 private float mStrokeMiter;
80 private float mTextSize;
81 private float mTextScaleX;
82 private float mTextSkewX;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -070083 private int mHintingMode = Paint.HINTING_ON;
Deepanshu Gupta8916b212014-06-11 15:40:47 -070084 // Variant of the font. A paint's variant can only be compact or elegant.
85 private FontVariant mFontVariant = FontVariant.COMPACT;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070086
Xavier Ducrohet91672792011-02-22 11:54:37 -080087 private Xfermode_Delegate mXfermode;
88 private ColorFilter_Delegate mColorFilter;
89 private Shader_Delegate mShader;
90 private PathEffect_Delegate mPathEffect;
91 private MaskFilter_Delegate mMaskFilter;
92 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -070093
Xavier Ducrohet43526ab2012-04-23 17:41:37 -070094 private Locale mLocale = Locale.getDefault();
95
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -070096 // Used only to assert invariants.
97 public long mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070098
99 // ---- Public Helper methods ----
100
Narayan Kamath633d6882014-01-27 14:24:16 +0000101 public static Paint_Delegate getDelegate(long native_paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700102 return sManager.getDelegate(native_paint);
103 }
104
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700105 /**
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700106 * Returns the list of {@link Font} objects.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700107 */
108 public List<FontInfo> getFonts() {
109 return mFonts;
110 }
111
Xavier Ducroheta313b652010-11-01 18:45:20 -0700112 public boolean isAntiAliased() {
113 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
114 }
115
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700116 public boolean isFilterBitmap() {
117 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
118 }
119
120 public int getStyle() {
121 return mStyle;
122 }
123
124 public int getColor() {
125 return mColor;
126 }
127
Xavier Ducrohet66225222010-12-21 01:33:04 -0800128 public int getAlpha() {
129 return mColor >>> 24;
130 }
131
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800132 public void setAlpha(int alpha) {
133 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
134 }
135
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700136 public int getTextAlign() {
137 return mTextAlign;
138 }
139
140 public float getStrokeWidth() {
141 return mStrokeWidth;
142 }
143
Xavier Ducrohet66225222010-12-21 01:33:04 -0800144 /**
145 * returns the value of stroke miter needed by the java api.
146 */
147 public float getJavaStrokeMiter() {
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800148 float miter = mStrokeMiter * mStrokeWidth;
149 if (miter < 1.f) {
150 miter = 1.f;
151 }
152 return miter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700153 }
154
155 public int getJavaCap() {
156 switch (Paint.sCapArray[mCap]) {
157 case BUTT:
158 return BasicStroke.CAP_BUTT;
159 case ROUND:
160 return BasicStroke.CAP_ROUND;
161 default:
162 case SQUARE:
163 return BasicStroke.CAP_SQUARE;
164 }
165 }
166
167 public int getJavaJoin() {
168 switch (Paint.sJoinArray[mJoin]) {
169 default:
170 case MITER:
171 return BasicStroke.JOIN_MITER;
172 case ROUND:
173 return BasicStroke.JOIN_ROUND;
174 case BEVEL:
175 return BasicStroke.JOIN_BEVEL;
176 }
177 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700178
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800179 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800180 if (mPathEffect != null) {
181 if (mPathEffect.isSupported()) {
182 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800183 assert stroke != null;
184 if (stroke != null) {
185 return stroke;
186 }
187 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800188 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800189 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800190 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800191 }
192 }
193
194 // if no custom stroke as been set, set the default one.
195 return new BasicStroke(
196 getStrokeWidth(),
197 getJavaCap(),
198 getJavaJoin(),
199 getJavaStrokeMiter());
200 }
201
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800202 /**
203 * Returns the {@link Xfermode} delegate or null if none have been set
204 *
205 * @return the delegate or null.
206 */
207 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800208 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700209 }
210
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800211 /**
212 * Returns the {@link ColorFilter} delegate or null if none have been set
213 *
214 * @return the delegate or null.
215 */
216 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800217 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700218 }
219
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800220 /**
221 * Returns the {@link Shader} delegate or null if none have been set
222 *
223 * @return the delegate or null.
224 */
225 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800226 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700227 }
228
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800229 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800230 * Returns the {@link MaskFilter} delegate or null if none have been set
231 *
232 * @return the delegate or null.
233 */
234 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800235 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800236 }
237
238 /**
239 * Returns the {@link Rasterizer} delegate or null if none have been set
240 *
241 * @return the delegate or null.
242 */
243 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800244 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700245 }
246
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700247 // ---- native methods ----
248
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800249 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700250 /*package*/ static int getFlags(Paint thisPaint) {
251 // get the delegate from the native int.
252 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
253 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700254 return 0;
255 }
256
257 return delegate.mFlags;
258 }
259
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700260
261
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800262 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700263 /*package*/ static void setFlags(Paint thisPaint, int flags) {
264 // get the delegate from the native int.
265 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
266 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700267 return;
268 }
269
270 delegate.mFlags = flags;
271 }
272
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800273 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700274 /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700275 setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700276 }
277
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800278 @LayoutlibDelegate
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -0700279 /*package*/ static int getHinting(Paint thisPaint) {
280 // get the delegate from the native int.
281 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
282 if (delegate == null) {
283 return Paint.HINTING_ON;
284 }
285
286 return delegate.mHintingMode;
287 }
288
289 @LayoutlibDelegate
290 /*package*/ static void setHinting(Paint thisPaint, int mode) {
291 // get the delegate from the native int.
292 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
293 if (delegate == null) {
294 return;
295 }
296
297 delegate.mHintingMode = mode;
298 }
299
300 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700301 /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
302 setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
303 }
304
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800305 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700306 /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
307 setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
308 }
309
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800310 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700311 /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
312 setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
313 }
314
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800315 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700316 /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
317 setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
318 }
319
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800320 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700321 /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
322 setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
323 }
324
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800325 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700326 /*package*/ static void setDither(Paint thisPaint, boolean dither) {
327 setFlag(thisPaint, Paint.DITHER_FLAG, dither);
328 }
329
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800330 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700331 /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
332 setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
333 }
334
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800335 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700336 /*package*/ static int getColor(Paint thisPaint) {
337 // get the delegate from the native int.
338 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
339 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700340 return 0;
341 }
342
343 return delegate.mColor;
344 }
345
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800346 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700347 /*package*/ static void setColor(Paint thisPaint, int color) {
348 // get the delegate from the native int.
349 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
350 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700351 return;
352 }
353
354 delegate.mColor = color;
355 }
356
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800357 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700358 /*package*/ static int getAlpha(Paint thisPaint) {
359 // get the delegate from the native int.
360 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
361 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700362 return 0;
363 }
364
Xavier Ducrohet66225222010-12-21 01:33:04 -0800365 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700366 }
367
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800368 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700369 /*package*/ static void setAlpha(Paint thisPaint, int a) {
370 // get the delegate from the native int.
371 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
372 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700373 return;
374 }
375
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800376 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700377 }
378
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800379 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700380 /*package*/ static float getStrokeWidth(Paint thisPaint) {
381 // get the delegate from the native int.
382 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
383 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700384 return 1.f;
385 }
386
387 return delegate.mStrokeWidth;
388 }
389
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800390 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700391 /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
392 // get the delegate from the native int.
393 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
394 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700395 return;
396 }
397
398 delegate.mStrokeWidth = width;
399 }
400
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800401 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700402 /*package*/ static float getStrokeMiter(Paint thisPaint) {
403 // get the delegate from the native int.
404 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
405 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700406 return 1.f;
407 }
408
409 return delegate.mStrokeMiter;
410 }
411
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800412 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700413 /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
414 // get the delegate from the native int.
415 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
416 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700417 return;
418 }
419
420 delegate.mStrokeMiter = miter;
421 }
422
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800423 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700424 /*package*/ static void native_setShadowLayer(long paint, float radius, float dx, float dy,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700425 int color) {
426 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800427 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800428 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700429 }
430
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800431 @LayoutlibDelegate
Deepanshu Gupta0bec6852014-05-15 09:30:11 -0700432 /*package*/ static boolean native_hasShadowLayer(long paint) {
433 // FIXME
434 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
435 "Paint.hasShadowLayer is not supported.", null, null /*data*/);
436 return false;
437 }
438
439 @LayoutlibDelegate
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700440 /*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700441 // get the delegate from the native int.
442 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700443 return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700444 }
445
446 @LayoutlibDelegate
447 /*package*/ static void setElegantTextHeight(Paint thisPaint, boolean elegant) {
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700448 // get the delegate from the native int.
449 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
450 if (delegate == null) {
451 return;
452 }
453
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -0700454 delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
Deepanshu Guptabd49b122014-04-18 15:43:06 -0700455 }
456
457 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700458 /*package*/ static float getTextSize(Paint thisPaint) {
459 // get the delegate from the native int.
460 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
461 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700462 return 1.f;
463 }
464
465 return delegate.mTextSize;
466 }
467
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800468 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700469 /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
470 // get the delegate from the native int.
471 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
472 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700473 return;
474 }
475
476 delegate.mTextSize = textSize;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800477 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700478 }
479
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800480 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700481 /*package*/ static float getTextScaleX(Paint thisPaint) {
482 // get the delegate from the native int.
483 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
484 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700485 return 1.f;
486 }
487
488 return delegate.mTextScaleX;
489 }
490
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800491 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700492 /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
493 // get the delegate from the native int.
494 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
495 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700496 return;
497 }
498
499 delegate.mTextScaleX = scaleX;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800500 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700501 }
502
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800503 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700504 /*package*/ static float getTextSkewX(Paint thisPaint) {
505 // get the delegate from the native int.
506 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
507 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700508 return 1.f;
509 }
510
511 return delegate.mTextSkewX;
512 }
513
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800514 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700515 /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
516 // get the delegate from the native int.
517 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
518 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700519 return;
520 }
521
522 delegate.mTextSkewX = skewX;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800523 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700524 }
525
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800526 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700527 /*package*/ static float ascent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800528 // get the delegate
529 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
530 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800531 return 0;
532 }
533
534 if (delegate.mFonts.size() > 0) {
535 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
536 // Android expects negative ascent so we invert the value from Java.
537 return - javaMetrics.getAscent();
538 }
539
540 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700541 }
542
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800543 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700544 /*package*/ static float descent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800545 // get the delegate
546 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
547 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 return javaMetrics.getDescent();
554 }
555
556 return 0;
557
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700558 }
559
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800560 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700561 /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700562 // get the delegate
563 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
564 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700565 return 0;
566 }
567
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800568 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700569 }
570
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800571 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700572 /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700573 // get the delegate
574 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
575 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700576 return 0;
577 }
578
579 if (delegate.mFonts.size() > 0) {
580 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
581 if (fmi != null) {
582 // Android expects negative ascent so we invert the value from Java.
583 fmi.top = - javaMetrics.getMaxAscent();
584 fmi.ascent = - javaMetrics.getAscent();
585 fmi.descent = javaMetrics.getDescent();
586 fmi.bottom = javaMetrics.getMaxDescent();
587 fmi.leading = javaMetrics.getLeading();
588 }
589
590 return javaMetrics.getHeight();
591 }
592
593 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700594 }
595
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800596 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700597 /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700598 int count, int bidiFlags) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700599 // get the delegate
600 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
601 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700602 return 0;
603 }
604
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700605 RectF bounds = delegate.measureText(text, index, count, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800606 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700607 }
608
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800609 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700610 /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end,
611 int bidiFlags) {
612 return native_measureText(thisPaint, text.toCharArray(), start, end - start, bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700613 }
614
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800615 @LayoutlibDelegate
Deepanshu Guptac398f182013-05-23 15:20:04 -0700616 /*package*/ static float native_measureText(Paint thisPaint, String text, int bidiFlags) {
617 return native_measureText(thisPaint, text.toCharArray(), 0, text.length(), bidiFlags);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700618 }
619
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800620 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700621 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, char[] text,
622 int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800623
624 // get the delegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700625 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800626 if (delegate == null) {
627 return 0;
628 }
629
630 int inc = count > 0 ? 1 : -1;
631
632 int measureIndex = 0;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800633 for (int i = index; i != index + count; i += inc, measureIndex++) {
634 int start, end;
635 if (i < index) {
636 start = i;
637 end = index;
638 } else {
639 start = index;
640 end = i;
641 }
642
643 // measure from start to end
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700644 RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -0800645 float res = bounds.right - bounds.left;
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800646
647 if (measuredWidth != null) {
648 measuredWidth[measureIndex] = res;
649 }
650
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -0800651 if (res > maxWidth) {
652 // we should not return this char index, but since it's 0-based
653 // and we need to return a count, we simply return measureIndex;
654 return measureIndex;
655 }
656
657 }
658
659 return measureIndex;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700660 }
661
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800662 @LayoutlibDelegate
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700663 /*package*/ static int native_breakText(long nativePaint, long nativeTypeface, String text,
664 boolean measureForwards,
Deepanshu Guptac398f182013-05-23 15:20:04 -0700665 float maxWidth, int bidiFlags, float[] measuredWidth) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700666 return native_breakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
667 maxWidth, bidiFlags, measuredWidth);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700668 }
669
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800670 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000671 /*package*/ static long native_init() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700672 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800673 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700674 }
675
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800676 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000677 /*package*/ static long native_initWithPaint(long paint) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700678 // get the delegate from the native int.
679 Paint_Delegate delegate = sManager.getDelegate(paint);
680 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700681 return 0;
682 }
683
684 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800685 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700686 }
687
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800688 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000689 /*package*/ static void native_reset(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700690 // get the delegate from the native int.
691 Paint_Delegate delegate = sManager.getDelegate(native_object);
692 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700693 return;
694 }
695
696 delegate.reset();
697 }
698
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800699 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000700 /*package*/ static void native_set(long native_dst, long native_src) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700701 // get the delegate from the native int.
702 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
703 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700704 return;
705 }
706
707 // get the delegate from the native int.
708 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
709 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700710 return;
711 }
712
713 delegate_dst.set(delegate_src);
714 }
715
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800716 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800717 /*package*/ static int native_getStyle(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700718 // get the delegate from the native int.
719 Paint_Delegate delegate = sManager.getDelegate(native_object);
720 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700721 return 0;
722 }
723
724 return delegate.mStyle;
725 }
726
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800727 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000728 /*package*/ static void native_setStyle(long native_object, int style) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700729 // get the delegate from the native int.
730 Paint_Delegate delegate = sManager.getDelegate(native_object);
731 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700732 return;
733 }
734
735 delegate.mStyle = style;
736 }
737
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800738 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800739 /*package*/ static int native_getStrokeCap(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700740 // get the delegate from the native int.
741 Paint_Delegate delegate = sManager.getDelegate(native_object);
742 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700743 return 0;
744 }
745
746 return delegate.mCap;
747 }
748
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800749 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000750 /*package*/ static void native_setStrokeCap(long native_object, int cap) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700751 // get the delegate from the native int.
752 Paint_Delegate delegate = sManager.getDelegate(native_object);
753 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700754 return;
755 }
756
757 delegate.mCap = cap;
758 }
759
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800760 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800761 /*package*/ static int native_getStrokeJoin(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700762 // get the delegate from the native int.
763 Paint_Delegate delegate = sManager.getDelegate(native_object);
764 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700765 return 0;
766 }
767
768 return delegate.mJoin;
769 }
770
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800771 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000772 /*package*/ static void native_setStrokeJoin(long native_object, int join) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700773 // get the delegate from the native int.
774 Paint_Delegate delegate = sManager.getDelegate(native_object);
775 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700776 return;
777 }
778
779 delegate.mJoin = join;
780 }
781
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800782 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000783 /*package*/ static boolean native_getFillPath(long native_object, long src, long dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800784 Paint_Delegate paint = sManager.getDelegate(native_object);
785 if (paint == null) {
786 return false;
787 }
788
789 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
790 if (srcPath == null) {
791 return true;
792 }
793
794 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
795 if (dstPath == null) {
796 return true;
797 }
798
799 Stroke stroke = paint.getJavaStroke();
800 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
801
802 dstPath.setJavaShape(strokeShape);
803
804 // FIXME figure out the return value?
805 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700806 }
807
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800808 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000809 /*package*/ static long native_setShader(long native_object, long shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700810 // get the delegate from the native int.
811 Paint_Delegate delegate = sManager.getDelegate(native_object);
812 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700813 return shader;
814 }
815
Xavier Ducrohet91672792011-02-22 11:54:37 -0800816 delegate.mShader = Shader_Delegate.getDelegate(shader);
817
818 return shader;
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_setColorFilter(long native_object, long filter) {
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 filter;
827 }
828
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700829 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800830
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700831 // Log warning if it's not supported.
832 if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800833 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800834 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800835 }
836
837 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700838 }
839
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800840 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000841 /*package*/ static long native_setXfermode(long native_object, long xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700842 // get the delegate from the native int.
843 Paint_Delegate delegate = sManager.getDelegate(native_object);
844 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700845 return xfermode;
846 }
847
Xavier Ducrohet91672792011-02-22 11:54:37 -0800848 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
849
850 return xfermode;
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_setPathEffect(long native_object, long effect) {
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 effect;
859 }
860
Xavier Ducrohet91672792011-02-22 11:54:37 -0800861 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
862
863 return effect;
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_setMaskFilter(long native_object, long maskfilter) {
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 maskfilter;
872 }
873
Xavier Ducrohet91672792011-02-22 11:54:37 -0800874 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800875
876 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700877 if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800878 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800879 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800880 }
881
882 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700883 }
884
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800885 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000886 /*package*/ static long native_setTypeface(long native_object, long typeface) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700887 // get the delegate from the native int.
888 Paint_Delegate delegate = sManager.getDelegate(native_object);
889 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700890 return 0;
891 }
892
Xavier Ducrohet91672792011-02-22 11:54:37 -0800893 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700894 delegate.mNativeTypeface = typeface;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800895 delegate.updateFontObject();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800896 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700897 }
898
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800899 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000900 /*package*/ static long native_setRasterizer(long native_object, long rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800901 // get the delegate from the native int.
902 Paint_Delegate delegate = sManager.getDelegate(native_object);
903 if (delegate == null) {
904 return rasterizer;
905 }
906
Xavier Ducrohet91672792011-02-22 11:54:37 -0800907 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800908
909 // since none of those are supported, display a fidelity warning right away
Deepanshu Gupta1128e782014-06-21 19:45:30 -0700910 if (delegate.mRasterizer != null && !delegate.mRasterizer.isSupported()) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800911 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800912 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800913 }
914
915 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700916 }
917
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800918 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800919 /*package*/ static int native_getTextAlign(long native_object) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700920 // get the delegate from the native int.
921 Paint_Delegate delegate = sManager.getDelegate(native_object);
922 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700923 return 0;
924 }
925
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700926 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700927 }
928
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800929 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000930 /*package*/ static void native_setTextAlign(long native_object, int align) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700931 // get the delegate from the native int.
932 Paint_Delegate delegate = sManager.getDelegate(native_object);
933 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700934 return;
935 }
936
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700937 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700938 }
939
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800940 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +0000941 /*package*/ static void native_setTextLocale(long native_object, String locale) {
Xavier Ducrohet43526ab2012-04-23 17:41:37 -0700942 // get the delegate from the native int.
943 Paint_Delegate delegate = sManager.getDelegate(native_object);
944 if (delegate == null) {
945 return;
946 }
947
948 delegate.setTextLocale(locale);
949 }
950
951 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700952 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
953 char[] text, int index, int count, int bidiFlags, float[] widths) {
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700954
955 if (widths != null) {
956 for (int i = 0; i< count; i++) {
957 widths[i]=0;
958 }
959 }
960 // get the delegate from the native int.
961 Paint_Delegate delegate = sManager.getDelegate(native_object);
962 if (delegate == null) {
963 return 0;
964 }
965
966 // native_typeface is passed here since Framework's old implementation did not have the
967 // typeface object associated with the Paint. Since, we follow the new framework way,
968 // we store the typeface with the paint and use it directly.
969 assert (native_typeface == delegate.mNativeTypeface);
970
971 RectF bounds = delegate.measureText(text, index, count, widths, 0, bidiFlags);
972 return ((int) (bounds.right - bounds.left));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700973 }
974
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800975 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700976 /*package*/ static int native_getTextWidths(long native_object, long native_typeface,
977 String text, int start, int end, int bidiFlags, float[] widths) {
978 return native_getTextWidths(native_object, native_typeface, text.toCharArray(), start,
979 end - start, bidiFlags, widths);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700980 }
981
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800982 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -0800983 /* package */static int native_getTextGlyphs(long native_object, String text, int start,
Xavier Ducrohet81efa7f2011-06-15 14:43:42 -0700984 int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
985 // FIXME
986 return 0;
987 }
988
989 @LayoutlibDelegate
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -0700990 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700991 char[] text, int index, int count, int contextIndex, int contextCount,
Deepanshu Gupta237740b2014-06-25 17:47:16 -0700992 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -0700993
994 if (advances != null)
995 for (int i = advancesIndex; i< advancesIndex+count; i++)
996 advances[i]=0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700997 // get the delegate from the native int.
998 Paint_Delegate delegate = sManager.getDelegate(native_object);
Deepanshu Gupta017c0622014-05-19 16:14:23 -0700999 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001000 return 0.f;
1001 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001002
1003 // native_typeface is passed here since Framework's old implementation did not have the
1004 // typeface object associated with the Paint. Since, we follow the new framework way,
1005 // we store the typeface with the paint and use it directly.
1006 assert (native_typeface == delegate.mNativeTypeface);
1007
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001008 RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, isRtl);
Deepanshu Guptaeb998d32014-01-07 11:58:44 -08001009 return bounds.right - bounds.left;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001010 }
1011
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001012 @LayoutlibDelegate
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001013 /*package*/ static float native_getTextRunAdvances(long native_object, long native_typeface,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001014 String text, int start, int end, int contextStart, int contextEnd,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001015 boolean isRtl, float[] advances, int advancesIndex) {
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001016 // FIXME: support contextStart and contextEnd
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001017 int count = end - start;
1018 char[] buffer = TemporaryBuffer.obtain(count);
1019 TextUtils.getChars(text, start, end, buffer, 0);
1020
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001021 return native_getTextRunAdvances(native_object, native_typeface, buffer, 0, count,
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001022 contextStart, contextEnd - contextStart, isRtl, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001023 }
1024
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001025 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001026 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001027 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
1028 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001029 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1030 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1031 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001032 }
1033
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001034 @LayoutlibDelegate
Deepanshu Guptaf9a82352014-02-21 16:22:10 -08001035 /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text,
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001036 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
1037 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001038 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1039 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
1040 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001041 }
1042
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001043 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001044 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1045 int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001046 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001047 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1048 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001049 }
1050
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001051 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001052 /*package*/ static void native_getTextPath(long native_object, long native_typeface,
1053 int bidiFlags, String text, int start, int end, float x, float y, long path) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001054 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -08001055 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
1056 "Paint.getTextPath is not supported.", null, null /*data*/);
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 nativeGetStringBounds(long nativePaint, long native_typeface,
1061 String text, int start, int end, int bidiFlags, Rect bounds) {
1062 nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
1063 end - start, bidiFlags, bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001064 }
1065
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001066 @LayoutlibDelegate
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001067 /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
1068 char[] text, int index, int count, int bidiFlags, Rect bounds) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001069
1070 // get the delegate from the native int.
1071 Paint_Delegate delegate = sManager.getDelegate(nativePaint);
Deepanshu Gupta017c0622014-05-19 16:14:23 -07001072 if (delegate == null) {
Xavier Ducrohetf4d52a62011-02-23 09:53:56 -08001073 return;
1074 }
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001075
1076 // assert that the typeface passed is actually the one that we had stored.
1077 assert (native_typeface == delegate.mNativeTypeface);
1078
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001079 delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001080 }
1081
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -08001082 @LayoutlibDelegate
Narayan Kamath633d6882014-01-27 14:24:16 +00001083 /*package*/ static void finalizer(long nativePaint) {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001084 sManager.removeJavaReferenceFor(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001085 }
1086
1087 // ---- Private delegate/helper methods ----
1088
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001089 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001090 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001091 }
1092
1093 private Paint_Delegate(Paint_Delegate paint) {
1094 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001095 }
1096
1097 private void set(Paint_Delegate paint) {
1098 mFlags = paint.mFlags;
1099 mColor = paint.mColor;
1100 mStyle = paint.mStyle;
1101 mCap = paint.mCap;
1102 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001103 mTextAlign = paint.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001104 mTypeface = paint.mTypeface;
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001105 mNativeTypeface = paint.mNativeTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001106 mStrokeWidth = paint.mStrokeWidth;
1107 mStrokeMiter = paint.mStrokeMiter;
1108 mTextSize = paint.mTextSize;
1109 mTextScaleX = paint.mTextScaleX;
1110 mTextSkewX = paint.mTextSkewX;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001111 mXfermode = paint.mXfermode;
1112 mColorFilter = paint.mColorFilter;
1113 mShader = paint.mShader;
1114 mPathEffect = paint.mPathEffect;
1115 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001116 mRasterizer = paint.mRasterizer;
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001117 mHintingMode = paint.mHintingMode;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001118 updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001119 }
1120
1121 private void reset() {
1122 mFlags = Paint.DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001123 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001124 mStyle = Paint.Style.FILL.nativeInt;
1125 mCap = Paint.Cap.BUTT.nativeInt;
1126 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001127 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001128 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Deepanshu Guptab1ce7c12014-06-05 14:18:54 -07001129 mNativeTypeface = 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001130 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001131 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001132 mTextSize = 20.f;
1133 mTextScaleX = 1.f;
1134 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001135 mXfermode = null;
1136 mColorFilter = null;
1137 mShader = null;
1138 mPathEffect = null;
1139 mMaskFilter = null;
1140 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001141 updateFontObject();
Xavier Ducrohetb6f7f572011-08-22 13:13:16 -07001142 mHintingMode = Paint.HINTING_ON;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001143 }
1144
1145 /**
1146 * Update the {@link Font} object from the typeface, text size and scaling
1147 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001148 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001149 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001150 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001151 // Get the fonts from the TypeFace object.
Deepanshu Gupta5a6b3ab2014-05-30 17:43:33 -07001152 List<Font> fonts = mTypeface.getFonts(mFontVariant);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001153
1154 // create new font objects as well as FontMetrics, based on the current text size
1155 // and skew info.
1156 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
1157 for (Font font : fonts) {
1158 FontInfo info = new FontInfo();
1159 info.mFont = font.deriveFont(mTextSize);
1160 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1161 // TODO: support skew
1162 info.mFont = info.mFont.deriveFont(new AffineTransform(
Xavier Ducrohet8f109102011-10-04 19:39:18 -07001163 mTextScaleX, mTextSkewX, 0, 1, 0, 0));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001164 }
Deepanshu Guptaa6b207a2013-07-12 11:38:05 -07001165 // The metrics here don't have anti-aliasing set.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001166 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1167
1168 infoList.add(info);
1169 }
1170
1171 mFonts = Collections.unmodifiableList(infoList);
1172 }
1173 }
1174
Deepanshu Gupta237740b2014-06-25 17:47:16 -07001175 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1176 int advancesIndex, int bidiFlags) {
1177 return new BidiRenderer(null, this, text)
1178 .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
1179 }
1180
1181 /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
1182 int advancesIndex, boolean isRtl) {
1183 return new BidiRenderer(null, this, text)
1184 .renderText(index, index + count, isRtl, advances, advancesIndex, false);
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001185 }
1186
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001187 private float getFontMetrics(FontMetrics metrics) {
1188 if (mFonts.size() > 0) {
1189 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1190 if (metrics != null) {
1191 // Android expects negative ascent so we invert the value from Java.
1192 metrics.top = - javaMetrics.getMaxAscent();
1193 metrics.ascent = - javaMetrics.getAscent();
1194 metrics.descent = javaMetrics.getDescent();
1195 metrics.bottom = javaMetrics.getMaxDescent();
1196 metrics.leading = javaMetrics.getLeading();
1197 }
1198
1199 return javaMetrics.getHeight();
1200 }
1201
1202 return 0;
1203 }
1204
Xavier Ducrohet43526ab2012-04-23 17:41:37 -07001205 private void setTextLocale(String locale) {
1206 mLocale = new Locale(locale);
1207 }
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001208
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001209 private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
1210 // get the delegate from the native int.
1211 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
1212 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001213 return;
1214 }
1215
1216 if (flagValue) {
1217 delegate.mFlags |= flagMask;
1218 } else {
1219 delegate.mFlags &= ~flagMask;
1220 }
1221 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001222}