blob: 74a91241ed50414175cbcd20ef6668795e7173ae [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
24import android.graphics.Paint.FontMetrics;
25import android.graphics.Paint.FontMetricsInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070026import android.text.TextUtils;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070027
Xavier Ducrohet37f21802010-11-01 16:17:18 -070028import java.awt.BasicStroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070029import java.awt.Font;
Xavier Ducrohetb9761242010-12-23 10:22:14 -080030import java.awt.Shape;
31import java.awt.Stroke;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070032import java.awt.Toolkit;
33import java.awt.font.FontRenderContext;
34import java.awt.geom.AffineTransform;
35import java.util.ArrayList;
36import java.util.Collections;
37import java.util.List;
38
39/**
40 * Delegate implementing the native methods of android.graphics.Paint
41 *
42 * Through the layoutlib_create tool, the original native methods of Paint have been replaced
43 * by calls to methods of the same name in this delegate class.
44 *
45 * This class behaves like the original native implementation, but in Java, keeping previously
46 * native data into its own objects and mapping them to int that are sent back and forth between
47 * it and the original Paint class.
48 *
49 * @see DelegateManager
50 *
51 */
52public class Paint_Delegate {
53
54 /**
55 * Class associating a {@link Font} and it's {@link java.awt.FontMetrics}.
56 */
Xavier Ducrohet37f21802010-11-01 16:17:18 -070057 /*package*/ static final class FontInfo {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070058 Font mFont;
59 java.awt.FontMetrics mMetrics;
60 }
61
62 // ---- delegate manager ----
63 private static final DelegateManager<Paint_Delegate> sManager =
64 new DelegateManager<Paint_Delegate>();
65
66 // ---- delegate helper data ----
67 private List<FontInfo> mFonts;
68 private final FontRenderContext mFontContext = new FontRenderContext(
69 new AffineTransform(), true, true);
70
71 // ---- delegate data ----
72 private int mFlags;
73 private int mColor;
74 private int mStyle;
75 private int mCap;
76 private int mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070077 private int mTextAlign;
Xavier Ducrohet91672792011-02-22 11:54:37 -080078 private Typeface_Delegate mTypeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070079 private float mStrokeWidth;
80 private float mStrokeMiter;
81 private float mTextSize;
82 private float mTextScaleX;
83 private float mTextSkewX;
84
Xavier Ducrohet91672792011-02-22 11:54:37 -080085 private Xfermode_Delegate mXfermode;
86 private ColorFilter_Delegate mColorFilter;
87 private Shader_Delegate mShader;
88 private PathEffect_Delegate mPathEffect;
89 private MaskFilter_Delegate mMaskFilter;
90 private Rasterizer_Delegate mRasterizer;
Xavier Ducroheta313b652010-11-01 18:45:20 -070091
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070092
93 // ---- Public Helper methods ----
94
Xavier Ducrohet37f21802010-11-01 16:17:18 -070095 public static Paint_Delegate getDelegate(int native_paint) {
96 return sManager.getDelegate(native_paint);
97 }
98
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070099 /**
100 * Returns the list of {@link Font} objects. The first item is the main font, the rest
101 * are fall backs for characters not present in the main font.
102 */
103 public List<FontInfo> getFonts() {
104 return mFonts;
105 }
106
Xavier Ducroheta313b652010-11-01 18:45:20 -0700107 public boolean isAntiAliased() {
108 return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
109 }
110
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700111 public boolean isFilterBitmap() {
112 return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
113 }
114
115 public int getStyle() {
116 return mStyle;
117 }
118
119 public int getColor() {
120 return mColor;
121 }
122
Xavier Ducrohet66225222010-12-21 01:33:04 -0800123 public int getAlpha() {
124 return mColor >>> 24;
125 }
126
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800127 public void setAlpha(int alpha) {
128 mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
129 }
130
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700131 public int getTextAlign() {
132 return mTextAlign;
133 }
134
135 public float getStrokeWidth() {
136 return mStrokeWidth;
137 }
138
Xavier Ducrohet66225222010-12-21 01:33:04 -0800139 /**
140 * returns the value of stroke miter needed by the java api.
141 */
142 public float getJavaStrokeMiter() {
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800143 float miter = mStrokeMiter * mStrokeWidth;
144 if (miter < 1.f) {
145 miter = 1.f;
146 }
147 return miter;
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700148 }
149
150 public int getJavaCap() {
151 switch (Paint.sCapArray[mCap]) {
152 case BUTT:
153 return BasicStroke.CAP_BUTT;
154 case ROUND:
155 return BasicStroke.CAP_ROUND;
156 default:
157 case SQUARE:
158 return BasicStroke.CAP_SQUARE;
159 }
160 }
161
162 public int getJavaJoin() {
163 switch (Paint.sJoinArray[mJoin]) {
164 default:
165 case MITER:
166 return BasicStroke.JOIN_MITER;
167 case ROUND:
168 return BasicStroke.JOIN_ROUND;
169 case BEVEL:
170 return BasicStroke.JOIN_BEVEL;
171 }
172 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700173
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800174 public Stroke getJavaStroke() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800175 if (mPathEffect != null) {
176 if (mPathEffect.isSupported()) {
177 Stroke stroke = mPathEffect.getStroke(this);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800178 assert stroke != null;
179 if (stroke != null) {
180 return stroke;
181 }
182 } else {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800183 Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800184 mPathEffect.getSupportMessage(),
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800185 null, null /*data*/);
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800186 }
187 }
188
189 // if no custom stroke as been set, set the default one.
190 return new BasicStroke(
191 getStrokeWidth(),
192 getJavaCap(),
193 getJavaJoin(),
194 getJavaStrokeMiter());
195 }
196
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800197 /**
198 * Returns the {@link Xfermode} delegate or null if none have been set
199 *
200 * @return the delegate or null.
201 */
202 public Xfermode_Delegate getXfermode() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800203 return mXfermode;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700204 }
205
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800206 /**
207 * Returns the {@link ColorFilter} delegate or null if none have been set
208 *
209 * @return the delegate or null.
210 */
211 public ColorFilter_Delegate getColorFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800212 return mColorFilter;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700213 }
214
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800215 /**
216 * Returns the {@link Shader} delegate or null if none have been set
217 *
218 * @return the delegate or null.
219 */
220 public Shader_Delegate getShader() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800221 return mShader;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700222 }
223
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800224 /**
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800225 * Returns the {@link MaskFilter} delegate or null if none have been set
226 *
227 * @return the delegate or null.
228 */
229 public MaskFilter_Delegate getMaskFilter() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800230 return mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800231 }
232
233 /**
234 * Returns the {@link Rasterizer} delegate or null if none have been set
235 *
236 * @return the delegate or null.
237 */
238 public Rasterizer_Delegate getRasterizer() {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800239 return mRasterizer;
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700240 }
241
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700242 // ---- native methods ----
243
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800244 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700245 /*package*/ static int getFlags(Paint thisPaint) {
246 // get the delegate from the native int.
247 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
248 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700249 return 0;
250 }
251
252 return delegate.mFlags;
253 }
254
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800255 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700256 /*package*/ static void setFlags(Paint thisPaint, int flags) {
257 // get the delegate from the native int.
258 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
259 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700260 return;
261 }
262
263 delegate.mFlags = flags;
264 }
265
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800266 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700267 /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700268 setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700269 }
270
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800271 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700272 /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
273 setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
274 }
275
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800276 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700277 /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
278 setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
279 }
280
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800281 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700282 /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
283 setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
284 }
285
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800286 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700287 /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
288 setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
289 }
290
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800291 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700292 /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
293 setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
294 }
295
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800296 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700297 /*package*/ static void setDither(Paint thisPaint, boolean dither) {
298 setFlag(thisPaint, Paint.DITHER_FLAG, dither);
299 }
300
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800301 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700302 /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
303 setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
304 }
305
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800306 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700307 /*package*/ static int getColor(Paint thisPaint) {
308 // get the delegate from the native int.
309 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
310 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700311 return 0;
312 }
313
314 return delegate.mColor;
315 }
316
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800317 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700318 /*package*/ static void setColor(Paint thisPaint, int color) {
319 // get the delegate from the native int.
320 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
321 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700322 return;
323 }
324
325 delegate.mColor = color;
326 }
327
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800328 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700329 /*package*/ static int getAlpha(Paint thisPaint) {
330 // get the delegate from the native int.
331 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
332 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700333 return 0;
334 }
335
Xavier Ducrohet66225222010-12-21 01:33:04 -0800336 return delegate.getAlpha();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700337 }
338
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800339 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700340 /*package*/ static void setAlpha(Paint thisPaint, int a) {
341 // get the delegate from the native int.
342 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
343 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700344 return;
345 }
346
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800347 delegate.setAlpha(a);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700348 }
349
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800350 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700351 /*package*/ static float getStrokeWidth(Paint thisPaint) {
352 // get the delegate from the native int.
353 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
354 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700355 return 1.f;
356 }
357
358 return delegate.mStrokeWidth;
359 }
360
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800361 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700362 /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
363 // get the delegate from the native int.
364 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
365 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700366 return;
367 }
368
369 delegate.mStrokeWidth = width;
370 }
371
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800372 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700373 /*package*/ static float getStrokeMiter(Paint thisPaint) {
374 // get the delegate from the native int.
375 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
376 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700377 return 1.f;
378 }
379
380 return delegate.mStrokeMiter;
381 }
382
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800383 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700384 /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
385 // get the delegate from the native int.
386 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
387 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700388 return;
389 }
390
391 delegate.mStrokeMiter = miter;
392 }
393
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800394 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700395 /*package*/ static void nSetShadowLayer(Paint thisPaint, float radius, float dx, float dy,
396 int color) {
397 // FIXME
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800398 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
Xavier Ducrohetf69bb292011-01-14 16:40:43 -0800399 "Paint.setShadowLayer is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700400 }
401
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800402 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700403 /*package*/ static float getTextSize(Paint thisPaint) {
404 // get the delegate from the native int.
405 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
406 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700407 return 1.f;
408 }
409
410 return delegate.mTextSize;
411 }
412
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800413 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700414 /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
415 // get the delegate from the native int.
416 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
417 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700418 return;
419 }
420
421 delegate.mTextSize = textSize;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800422 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700423 }
424
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800425 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700426 /*package*/ static float getTextScaleX(Paint thisPaint) {
427 // get the delegate from the native int.
428 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
429 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700430 return 1.f;
431 }
432
433 return delegate.mTextScaleX;
434 }
435
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800436 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700437 /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
438 // get the delegate from the native int.
439 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
440 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700441 return;
442 }
443
444 delegate.mTextScaleX = scaleX;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800445 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700446 }
447
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800448 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700449 /*package*/ static float getTextSkewX(Paint thisPaint) {
450 // get the delegate from the native int.
451 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
452 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700453 return 1.f;
454 }
455
456 return delegate.mTextSkewX;
457 }
458
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800459 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700460 /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
461 // get the delegate from the native int.
462 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
463 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700464 return;
465 }
466
467 delegate.mTextSkewX = skewX;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800468 delegate.updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700469 }
470
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800471 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700472 /*package*/ static float ascent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800473 // get the delegate
474 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
475 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800476 return 0;
477 }
478
479 if (delegate.mFonts.size() > 0) {
480 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
481 // Android expects negative ascent so we invert the value from Java.
482 return - javaMetrics.getAscent();
483 }
484
485 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700486 }
487
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800488 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700489 /*package*/ static float descent(Paint thisPaint) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800490 // get the delegate
491 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
492 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800493 return 0;
494 }
495
496 if (delegate.mFonts.size() > 0) {
497 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
498 return javaMetrics.getDescent();
499 }
500
501 return 0;
502
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700503 }
504
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800505 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700506 /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700507 // get the delegate
508 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
509 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700510 return 0;
511 }
512
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800513 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700514 }
515
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800516 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700517 /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700518 // get the delegate
519 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
520 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700521 return 0;
522 }
523
524 if (delegate.mFonts.size() > 0) {
525 java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
526 if (fmi != null) {
527 // Android expects negative ascent so we invert the value from Java.
528 fmi.top = - javaMetrics.getMaxAscent();
529 fmi.ascent = - javaMetrics.getAscent();
530 fmi.descent = javaMetrics.getDescent();
531 fmi.bottom = javaMetrics.getMaxDescent();
532 fmi.leading = javaMetrics.getLeading();
533 }
534
535 return javaMetrics.getHeight();
536 }
537
538 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700539 }
540
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800541 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700542 /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
543 int count) {
544 // WARNING: the logic in this method is similar to Canvas.drawText.
545 // Any change to this method should be reflected in Canvas.drawText
546
547 // get the delegate
548 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
549 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700550 return 0;
551 }
552
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700553 return delegate.measureText(text, index, count);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700554 }
555
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800556 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700557 /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end) {
558 return native_measureText(thisPaint, text.toCharArray(), start, end - start);
559 }
560
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800561 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700562 /*package*/ static float native_measureText(Paint thisPaint, String text) {
563 return native_measureText(thisPaint, text.toCharArray(), 0, text.length());
564 }
565
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800566 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700567 /*package*/ static int native_breakText(Paint thisPaint, char[] text, int index, int count,
568 float maxWidth, float[] measuredWidth) {
569 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800570 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
571 "Paint.native_breakText is not supported.", null, null /*data*/);
572 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700573 }
574
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800575 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700576 /*package*/ static int native_breakText(Paint thisPaint, String text, boolean measureForwards,
577 float maxWidth, float[] measuredWidth) {
578 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800579 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
580 "Paint.native_breakText is not supported.", null, null /*data*/);
581 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700582 }
583
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800584 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700585 /*package*/ static int native_init() {
586 Paint_Delegate newDelegate = new Paint_Delegate();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800587 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700588 }
589
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800590 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700591 /*package*/ static int native_initWithPaint(int paint) {
592 // get the delegate from the native int.
593 Paint_Delegate delegate = sManager.getDelegate(paint);
594 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700595 return 0;
596 }
597
598 Paint_Delegate newDelegate = new Paint_Delegate(delegate);
Xavier Ducrohet91672792011-02-22 11:54:37 -0800599 return sManager.addNewDelegate(newDelegate);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700600 }
601
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800602 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700603 /*package*/ static void native_reset(int native_object) {
604 // get the delegate from the native int.
605 Paint_Delegate delegate = sManager.getDelegate(native_object);
606 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700607 return;
608 }
609
610 delegate.reset();
611 }
612
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800613 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700614 /*package*/ static void native_set(int native_dst, int native_src) {
615 // get the delegate from the native int.
616 Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
617 if (delegate_dst == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700618 return;
619 }
620
621 // get the delegate from the native int.
622 Paint_Delegate delegate_src = sManager.getDelegate(native_src);
623 if (delegate_src == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700624 return;
625 }
626
627 delegate_dst.set(delegate_src);
628 }
629
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800630 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700631 /*package*/ static int native_getStyle(int native_object) {
632 // get the delegate from the native int.
633 Paint_Delegate delegate = sManager.getDelegate(native_object);
634 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700635 return 0;
636 }
637
638 return delegate.mStyle;
639 }
640
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800641 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700642 /*package*/ static void native_setStyle(int native_object, int style) {
643 // get the delegate from the native int.
644 Paint_Delegate delegate = sManager.getDelegate(native_object);
645 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700646 return;
647 }
648
649 delegate.mStyle = style;
650 }
651
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800652 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700653 /*package*/ static int native_getStrokeCap(int native_object) {
654 // get the delegate from the native int.
655 Paint_Delegate delegate = sManager.getDelegate(native_object);
656 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700657 return 0;
658 }
659
660 return delegate.mCap;
661 }
662
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800663 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700664 /*package*/ static void native_setStrokeCap(int native_object, int cap) {
665 // get the delegate from the native int.
666 Paint_Delegate delegate = sManager.getDelegate(native_object);
667 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700668 return;
669 }
670
671 delegate.mCap = cap;
672 }
673
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800674 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700675 /*package*/ static int native_getStrokeJoin(int native_object) {
676 // get the delegate from the native int.
677 Paint_Delegate delegate = sManager.getDelegate(native_object);
678 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700679 return 0;
680 }
681
682 return delegate.mJoin;
683 }
684
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800685 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700686 /*package*/ static void native_setStrokeJoin(int native_object, int join) {
687 // get the delegate from the native int.
688 Paint_Delegate delegate = sManager.getDelegate(native_object);
689 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700690 return;
691 }
692
693 delegate.mJoin = join;
694 }
695
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800696 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700697 /*package*/ static boolean native_getFillPath(int native_object, int src, int dst) {
Xavier Ducrohetb9761242010-12-23 10:22:14 -0800698 Paint_Delegate paint = sManager.getDelegate(native_object);
699 if (paint == null) {
700 return false;
701 }
702
703 Path_Delegate srcPath = Path_Delegate.getDelegate(src);
704 if (srcPath == null) {
705 return true;
706 }
707
708 Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
709 if (dstPath == null) {
710 return true;
711 }
712
713 Stroke stroke = paint.getJavaStroke();
714 Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
715
716 dstPath.setJavaShape(strokeShape);
717
718 // FIXME figure out the return value?
719 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700720 }
721
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800722 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700723 /*package*/ static int native_setShader(int native_object, int shader) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700724 // get the delegate from the native int.
725 Paint_Delegate delegate = sManager.getDelegate(native_object);
726 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700727 return shader;
728 }
729
Xavier Ducrohet91672792011-02-22 11:54:37 -0800730 delegate.mShader = Shader_Delegate.getDelegate(shader);
731
732 return shader;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700733 }
734
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800735 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700736 /*package*/ static int native_setColorFilter(int native_object, int filter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700737 // get the delegate from the native int.
738 Paint_Delegate delegate = sManager.getDelegate(native_object);
739 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700740 return filter;
741 }
742
Xavier Ducrohet91672792011-02-22 11:54:37 -0800743 delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800744
745 // since none of those are supported, display a fidelity warning right away
Xavier Ducrohet91672792011-02-22 11:54:37 -0800746 if (delegate.mColorFilter != null && delegate.mColorFilter.isSupported() == false) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800747 Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800748 delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800749 }
750
751 return filter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700752 }
753
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800754 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700755 /*package*/ static int native_setXfermode(int native_object, int xfermode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700756 // get the delegate from the native int.
757 Paint_Delegate delegate = sManager.getDelegate(native_object);
758 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700759 return xfermode;
760 }
761
Xavier Ducrohet91672792011-02-22 11:54:37 -0800762 delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
763
764 return xfermode;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700765 }
766
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800767 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700768 /*package*/ static int native_setPathEffect(int native_object, int effect) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700769 // get the delegate from the native int.
770 Paint_Delegate delegate = sManager.getDelegate(native_object);
771 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700772 return effect;
773 }
774
Xavier Ducrohet91672792011-02-22 11:54:37 -0800775 delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
776
777 return effect;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700778 }
779
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800780 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700781 /*package*/ static int native_setMaskFilter(int native_object, int maskfilter) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700782 // get the delegate from the native int.
783 Paint_Delegate delegate = sManager.getDelegate(native_object);
784 if (delegate == null) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700785 return maskfilter;
786 }
787
Xavier Ducrohet91672792011-02-22 11:54:37 -0800788 delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800789
790 // since none of those are supported, display a fidelity warning right away
Xavier Ducrohet91672792011-02-22 11:54:37 -0800791 if (delegate.mMaskFilter != null && delegate.mMaskFilter.isSupported() == false) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800792 Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800793 delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800794 }
795
796 return maskfilter;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700797 }
798
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800799 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700800 /*package*/ static int native_setTypeface(int native_object, int typeface) {
801 // get the delegate from the native int.
802 Paint_Delegate delegate = sManager.getDelegate(native_object);
803 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700804 return 0;
805 }
806
Xavier Ducrohet91672792011-02-22 11:54:37 -0800807 delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
Xavier Ducrohet42e2b282010-12-06 11:08:37 -0800808 delegate.updateFontObject();
Xavier Ducrohet91672792011-02-22 11:54:37 -0800809 return typeface;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700810 }
811
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800812 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700813 /*package*/ static int native_setRasterizer(int native_object, int rasterizer) {
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800814 // get the delegate from the native int.
815 Paint_Delegate delegate = sManager.getDelegate(native_object);
816 if (delegate == null) {
817 return rasterizer;
818 }
819
Xavier Ducrohet91672792011-02-22 11:54:37 -0800820 delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800821
822 // since none of those are supported, display a fidelity warning right away
Xavier Ducrohet91672792011-02-22 11:54:37 -0800823 if (delegate.mRasterizer != null && delegate.mRasterizer.isSupported() == false) {
Xavier Ducrohet3f9b0372011-01-13 10:59:34 -0800824 Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
Xavier Ducrohet91672792011-02-22 11:54:37 -0800825 delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
Xavier Ducroheta6e51d52010-12-23 07:16:21 -0800826 }
827
828 return rasterizer;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700829 }
830
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800831 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700832 /*package*/ static int native_getTextAlign(int native_object) {
833 // get the delegate from the native int.
834 Paint_Delegate delegate = sManager.getDelegate(native_object);
835 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700836 return 0;
837 }
838
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700839 return delegate.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700840 }
841
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800842 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700843 /*package*/ static void native_setTextAlign(int native_object, int align) {
844 // get the delegate from the native int.
845 Paint_Delegate delegate = sManager.getDelegate(native_object);
846 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700847 return;
848 }
849
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700850 delegate.mTextAlign = align;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700851 }
852
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800853 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700854 /*package*/ static float native_getFontMetrics(int native_paint, FontMetrics metrics) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800855 // get the delegate from the native int.
856 Paint_Delegate delegate = sManager.getDelegate(native_paint);
857 if (delegate == null) {
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -0800858 return 0.f;
859 }
860
861 return delegate.getFontMetrics(metrics);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700862 }
863
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800864 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700865 /*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
866 int count, float[] widths) {
867 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800868 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
869 "Paint.getTextWidths is not supported.", null, null /*data*/);
870 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700871 }
872
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800873 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700874 /*package*/ static int native_getTextWidths(int native_object, String text, int start,
875 int end, float[] widths) {
876 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800877 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
878 "Paint.getTextWidths is not supported.", null, null /*data*/);
879 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700880 }
881
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800882 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700883 /*package*/ static float native_getTextRunAdvances(int native_object,
884 char[] text, int index, int count, int contextIndex, int contextCount,
885 int flags, float[] advances, int advancesIndex) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700886 // get the delegate from the native int.
887 Paint_Delegate delegate = sManager.getDelegate(native_object);
888 if (delegate == null) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700889 return 0.f;
890 }
891
892 if (delegate.mFonts.size() > 0) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700893 // FIXME: handle multi-char characters (see measureText)
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700894 float totalAdvance = 0;
895 for (int i = 0; i < count; i++) {
896 char c = text[i + index];
897 boolean found = false;
898 for (FontInfo info : delegate.mFonts) {
899 if (info.mFont.canDisplay(c)) {
900 float adv = info.mMetrics.charWidth(c);
901 totalAdvance += adv;
902 if (advances != null) {
903 advances[i] = adv;
904 }
905
906 found = true;
907 break;
908 }
909 }
910
911 if (found == false) {
912 // no advance for this char.
913 if (advances != null) {
914 advances[i] = 0.f;
915 }
916 }
917 }
918
919 return totalAdvance;
920 }
921
922 return 0;
923
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700924 }
925
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800926 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700927 /*package*/ static float native_getTextRunAdvances(int native_object,
928 String text, int start, int end, int contextStart, int contextEnd,
929 int flags, float[] advances, int advancesIndex) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700930 // FIXME: support contextStart, contextEnd and direction flag
931 int count = end - start;
932 char[] buffer = TemporaryBuffer.obtain(count);
933 TextUtils.getChars(text, start, end, buffer, 0);
934
935 return native_getTextRunAdvances(native_object, buffer, 0, count, contextStart,
936 contextEnd - contextStart, flags, advances, advancesIndex);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700937 }
938
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800939 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700940 /*package*/ static int native_getTextRunCursor(Paint thisPaint, int native_object, char[] text,
941 int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
942 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800943 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
944 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
945 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700946 }
947
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800948 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700949 /*package*/ static int native_getTextRunCursor(Paint thisPaint, int native_object, String text,
950 int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
951 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800952 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
953 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
954 return 0;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700955 }
956
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800957 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700958 /*package*/ static void native_getTextPath(int native_object, int bidiFlags,
959 char[] text, int index, int count, float x, float y, int path) {
960 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800961 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
962 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700963 }
964
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800965 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700966 /*package*/ static void native_getTextPath(int native_object, int bidiFlags,
967 String text, int start, int end, float x, float y, int path) {
968 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800969 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
970 "Paint.getTextPath is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700971 }
972
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800973 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700974 /*package*/ static void nativeGetStringBounds(int nativePaint, String text, int start,
975 int end, Rect bounds) {
976 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800977 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
978 "Paint.getStringBounds is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700979 }
980
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800981 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700982 /*package*/ static void nativeGetCharArrayBounds(int nativePaint, char[] text, int index,
983 int count, Rect bounds) {
984 // FIXME
Xavier Ducrohet1eeaea02011-02-09 19:39:52 -0800985 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
986 "Paint.getCharArrayBounds is not supported.", null, null /*data*/);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700987 }
988
Xavier Ducrohet94c80bf2011-02-09 17:17:49 -0800989 @LayoutlibDelegate
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700990 /*package*/ static void finalizer(int nativePaint) {
Xavier Ducrohet91672792011-02-22 11:54:37 -0800991 sManager.removeJavaReferenceFor(nativePaint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700992 }
993
994 // ---- Private delegate/helper methods ----
995
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -0800996 /*package*/ Paint_Delegate() {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700997 reset();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700998 }
999
1000 private Paint_Delegate(Paint_Delegate paint) {
1001 set(paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001002 }
1003
1004 private void set(Paint_Delegate paint) {
1005 mFlags = paint.mFlags;
1006 mColor = paint.mColor;
1007 mStyle = paint.mStyle;
1008 mCap = paint.mCap;
1009 mJoin = paint.mJoin;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001010 mTextAlign = paint.mTextAlign;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001011 mTypeface = paint.mTypeface;
1012 mStrokeWidth = paint.mStrokeWidth;
1013 mStrokeMiter = paint.mStrokeMiter;
1014 mTextSize = paint.mTextSize;
1015 mTextScaleX = paint.mTextScaleX;
1016 mTextSkewX = paint.mTextSkewX;
Xavier Ducroheta313b652010-11-01 18:45:20 -07001017 mXfermode = paint.mXfermode;
1018 mColorFilter = paint.mColorFilter;
1019 mShader = paint.mShader;
1020 mPathEffect = paint.mPathEffect;
1021 mMaskFilter = paint.mMaskFilter;
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001022 mRasterizer = paint.mRasterizer;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001023 updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001024 }
1025
1026 private void reset() {
1027 mFlags = Paint.DEFAULT_PAINT_FLAGS;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001028 mColor = 0xFF000000;
Xavier Ducrohet66225222010-12-21 01:33:04 -08001029 mStyle = Paint.Style.FILL.nativeInt;
1030 mCap = Paint.Cap.BUTT.nativeInt;
1031 mJoin = Paint.Join.MITER.nativeInt;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001032 mTextAlign = 0;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001033 mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001034 mStrokeWidth = 1.f;
Xavier Ducrohetcf2030c2010-12-21 06:20:28 -08001035 mStrokeMiter = 4.f;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001036 mTextSize = 20.f;
1037 mTextScaleX = 1.f;
1038 mTextSkewX = 0.f;
Xavier Ducrohet91672792011-02-22 11:54:37 -08001039 mXfermode = null;
1040 mColorFilter = null;
1041 mShader = null;
1042 mPathEffect = null;
1043 mMaskFilter = null;
1044 mRasterizer = null;
Xavier Ducrohet42e2b282010-12-06 11:08:37 -08001045 updateFontObject();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001046 }
1047
1048 /**
1049 * Update the {@link Font} object from the typeface, text size and scaling
1050 */
Xavier Ducroheta6e51d52010-12-23 07:16:21 -08001051 @SuppressWarnings("deprecation")
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001052 private void updateFontObject() {
Xavier Ducrohet91672792011-02-22 11:54:37 -08001053 if (mTypeface != null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001054 // Get the fonts from the TypeFace object.
Xavier Ducrohet91672792011-02-22 11:54:37 -08001055 List<Font> fonts = mTypeface.getFonts();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001056
1057 // create new font objects as well as FontMetrics, based on the current text size
1058 // and skew info.
1059 ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
1060 for (Font font : fonts) {
1061 FontInfo info = new FontInfo();
1062 info.mFont = font.deriveFont(mTextSize);
1063 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
1064 // TODO: support skew
1065 info.mFont = info.mFont.deriveFont(new AffineTransform(
1066 mTextScaleX, mTextSkewX, 0, 0, 1, 0));
1067 }
1068 info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
1069
1070 infoList.add(info);
1071 }
1072
1073 mFonts = Collections.unmodifiableList(infoList);
1074 }
1075 }
1076
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001077 /*package*/ float measureText(char[] text, int index, int count) {
1078 if (mFonts.size() > 0) {
1079 FontInfo mainFont = mFonts.get(0);
1080 int i = index;
1081 int lastIndex = index + count;
1082 float total = 0f;
1083 while (i < lastIndex) {
1084 // always start with the main font.
1085 int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
1086 if (upTo == -1) {
1087 // shortcut to exit
1088 return total + mainFont.mMetrics.charsWidth(text, i, lastIndex - i);
1089 } else if (upTo > 0) {
1090 total += mainFont.mMetrics.charsWidth(text, i, upTo - i);
1091 i = upTo;
1092 // don't call continue at this point. Since it is certain the main font
1093 // cannot display the font a index upTo (now ==i), we move on to the
1094 // fallback fonts directly.
1095 }
1096
1097 // no char supported, attempt to read the next char(s) with the
1098 // fallback font. In this case we only test the first character
1099 // and then go back to test with the main font.
1100 // Special test for 2-char characters.
1101 boolean foundFont = false;
1102 for (int f = 1 ; f < mFonts.size() ; f++) {
1103 FontInfo fontInfo = mFonts.get(f);
1104
1105 // need to check that the font can display the character. We test
1106 // differently if the char is a high surrogate.
1107 int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
1108 upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
1109 if (upTo == -1) {
1110 total += fontInfo.mMetrics.charsWidth(text, i, charCount);
1111 i += charCount;
1112 foundFont = true;
1113 break;
1114
1115 }
1116 }
1117
1118 // in case no font can display the char, measure it with the main font.
1119 if (foundFont == false) {
1120 int size = Character.isHighSurrogate(text[i]) ? 2 : 1;
1121 total += mainFont.mMetrics.charsWidth(text, i, size);
1122 i += size;
1123 }
1124 }
1125 }
1126
1127 return 0;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001128 }
1129
Xavier Ducrohetdf67eab2010-12-13 16:42:01 -08001130 private float getFontMetrics(FontMetrics metrics) {
1131 if (mFonts.size() > 0) {
1132 java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
1133 if (metrics != null) {
1134 // Android expects negative ascent so we invert the value from Java.
1135 metrics.top = - javaMetrics.getMaxAscent();
1136 metrics.ascent = - javaMetrics.getAscent();
1137 metrics.descent = javaMetrics.getDescent();
1138 metrics.bottom = javaMetrics.getMaxDescent();
1139 metrics.leading = javaMetrics.getLeading();
1140 }
1141
1142 return javaMetrics.getHeight();
1143 }
1144
1145 return 0;
1146 }
1147
1148
1149
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001150 private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
1151 // get the delegate from the native int.
1152 Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
1153 if (delegate == null) {
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001154 return;
1155 }
1156
1157 if (flagValue) {
1158 delegate.mFlags |= flagMask;
1159 } else {
1160 delegate.mFlags &= ~flagMask;
1161 }
1162 }
1163}