Paint.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/*
2 * Copyright (C) 2006 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
19import android.text.TextUtils;
20import android.text.SpannableString;
21import android.text.SpannedString;
22import android.text.GraphicsOperations;
23
24/**
25 * The Paint class holds the style and color information about how to draw
26 * geometries, text and bitmaps.
27 */
28public class Paint {
29
30    /*package*/ int     mNativePaint;
31    private ColorFilter mColorFilter;
32    private MaskFilter  mMaskFilter;
33    private PathEffect  mPathEffect;
34    private Rasterizer  mRasterizer;
35    private Shader      mShader;
36    private Typeface    mTypeface;
37    private Xfermode    mXfermode;
38
39    private static final Style[] sStyleArray = {
40        Style.FILL, Style.STROKE, Style.FILL_AND_STROKE
41    };
42    private static final Cap[] sCapArray = {
43        Cap.BUTT, Cap.ROUND, Cap.SQUARE
44    };
45    private static final Join[] sJoinArray = {
46        Join.MITER, Join.ROUND, Join.BEVEL
47    };
48    private static final Align[] sAlignArray = {
49        Align.LEFT, Align.CENTER, Align.RIGHT
50    };
51
52    /** bit mask for the flag enabling antialiasing */
53    public static final int ANTI_ALIAS_FLAG     = 0x01;
54    /** bit mask for the flag enabling bitmap filtering */
55    public static final int FILTER_BITMAP_FLAG  = 0x02;
56    /** bit mask for the flag enabling dithering */
57    public static final int DITHER_FLAG         = 0x04;
58    /** bit mask for the flag enabling underline text */
59    public static final int UNDERLINE_TEXT_FLAG = 0x08;
60    /** bit mask for the flag enabling strike-thru text */
61    public static final int STRIKE_THRU_TEXT_FLAG = 0x10;
62    /** bit mask for the flag enabling fake-bold text */
63    public static final int FAKE_BOLD_TEXT_FLAG = 0x20;
64    /** bit mask for the flag enabling linear-text (no caching) */
65    public static final int LINEAR_TEXT_FLAG    = 0x40;
66    /** bit mask for the flag enabling subpixel-text */
67    public static final int SUBPIXEL_TEXT_FLAG  = 0x80;
68    /** bit mask for the flag enabling device kerning for text */
69    public static final int DEV_KERN_TEXT_FLAG  = 0x100;
70
71    // we use this when we first create a paint
72    private static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG;
73
74    /**
75     * The Style specifies if the primitive being drawn is filled,
76     * stroked, or both (in the same color). The default is FILL.
77     */
78    public enum Style {
79        /**
80         * Geometry and text drawn with this style will be filled, ignoring all
81         * stroke-related settings in the paint.
82         */
83        FILL            (0),
84        /**
85         * Geometry and text drawn with this style will be stroked, respecting
86         * the stroke-related fields on the paint.
87         */
88        STROKE          (1),
89        /**
90         * Geometry and text drawn with this style will be both filled and
91         * stroked at the same time, respecting the stroke-related fields on
92         * the paint.
93         */
94        FILL_AND_STROKE (2);
95
96        Style(int nativeInt) {
97            this.nativeInt = nativeInt;
98        }
99        final int nativeInt;
100    }
101
102    /**
103     * The Cap specifies the treatment for the beginning and ending of
104     * stroked lines and paths. The default is BUTT.
105     */
106    public enum Cap {
107        /**
108         * The stroke ends with the path, and does not project beyond it.
109         */
110        BUTT    (0),
111        /**
112         * The stroke projects out as a square, with the center at the end
113         * of the path.
114         */
115        ROUND   (1),
116        /**
117         * The stroke projects out as a semicircle, with the center at the
118         * end of the path.
119         */
120        SQUARE  (2);
121
122        private Cap(int nativeInt) {
123            this.nativeInt = nativeInt;
124        }
125        final int nativeInt;
126    }
127
128    /**
129     * The Join specifies the treatment where lines and curve segments
130     * join on a stroked path. The default is MITER.
131     */
132    public enum Join {
133        /**
134         * The outer edges of a join meet at a sharp angle
135         */
136        MITER   (0),
137        /**
138         * The outer edges of a join meet in a circular arc.
139         */
140        ROUND   (1),
141        /**
142         * The outer edges of a join meet with a straight line
143         */
144        BEVEL   (2);
145
146        private Join(int nativeInt) {
147            this.nativeInt = nativeInt;
148        }
149        final int nativeInt;
150    }
151
152    /**
153     * Align specifies how drawText aligns its text relative to the
154     * [x,y] coordinates. The default is LEFT.
155     */
156    public enum Align {
157        /**
158         * The text is drawn to the right of the x,y origin
159         */
160        LEFT    (0),
161        /**
162         * The text is drawn centered horizontally on the x,y origin
163         */
164        CENTER  (1),
165        /**
166         * The text is drawn to the left of the x,y origin
167         */
168        RIGHT   (2);
169
170        private Align(int nativeInt) {
171            this.nativeInt = nativeInt;
172        }
173        final int nativeInt;
174    }
175
176    /**
177     * Create a new paint with default settings.
178     */
179    public Paint() {
180        this(0);
181    }
182
183    /**
184     * Create a new paint with the specified flags. Use setFlags() to change
185     * these after the paint is created.
186     *
187     * @param flags initial flag bits, as if they were passed via setFlags().
188     */
189    public Paint(int flags) {
190        mNativePaint = native_init();
191        setFlags(flags | DEFAULT_PAINT_FLAGS);
192    }
193
194    /**
195     * Create a new paint, initialized with the attributes in the specified
196     * paint parameter.
197     *
198     * @param paint Existing paint used to initialized the attributes of the
199     *              new paint.
200     */
201    public Paint(Paint paint) {
202        mNativePaint = native_initWithPaint(paint.mNativePaint);
203    }
204
205    /** Restores the paint to its default settings. */
206    public void reset() {
207        native_reset(mNativePaint);
208        setFlags(DEFAULT_PAINT_FLAGS);
209    }
210
211    /**
212     * Copy the fields from src into this paint. This is equivalent to calling
213     * get() on all of the src fields, and calling the corresponding set()
214     * methods on this.
215     */
216    public void set(Paint src) {
217        if (this != src) {
218            // copy over the native settings
219            native_set(mNativePaint, src.mNativePaint);
220            // copy over our java settings
221            mColorFilter    = src.mColorFilter;
222            mMaskFilter     = src.mMaskFilter;
223            mPathEffect     = src.mPathEffect;
224            mRasterizer     = src.mRasterizer;
225            mShader         = src.mShader;
226            mTypeface       = src.mTypeface;
227            mXfermode       = src.mXfermode;
228        }
229    }
230
231    /**
232     * Return the paint's flags. Use the Flag enum to test flag values.
233     *
234     * @return the paint's flags (see enums ending in _Flag for bit masks)
235     */
236    public native int getFlags();
237
238    /**
239     * Set the paint's flags. Use the Flag enum to specific flag values.
240     *
241     * @param flags The new flag bits for the paint
242     */
243    public native void setFlags(int flags);
244
245    /**
246     * Helper for getFlags(), returning true if ANTI_ALIAS_FLAG bit is set
247     * AntiAliasing smooths out the edges of what is being drawn, but is has
248     * no impact on the interior of the shape. See setDither() and
249     * setFilterBitmap() to affect how colors are treated.
250     *
251     * @return true if the antialias bit is set in the paint's flags.
252     */
253    public final boolean isAntiAlias() {
254        return (getFlags() & ANTI_ALIAS_FLAG) != 0;
255    }
256
257    /**
258     * Helper for setFlags(), setting or clearing the ANTI_ALIAS_FLAG bit
259     * AntiAliasing smooths out the edges of what is being drawn, but is has
260     * no impact on the interior of the shape. See setDither() and
261     * setFilterBitmap() to affect how colors are treated.
262     *
263     * @param aa true to set the antialias bit in the flags, false to clear it
264     */
265    public native void setAntiAlias(boolean aa);
266
267    /**
268     * Helper for getFlags(), returning true if DITHER_FLAG bit is set
269     * Dithering affects how colors that are higher precision than the device
270     * are down-sampled. No dithering is generally faster, but higher precision
271     * colors are just truncated down (e.g. 8888 -> 565). Dithering tries to
272     * distribute the error inherent in this process, to reduce the visual
273     * artifacts.
274     *
275     * @return true if the dithering bit is set in the paint's flags.
276     */
277    public final boolean isDither() {
278        return (getFlags() & DITHER_FLAG) != 0;
279    }
280
281    /**
282     * Helper for setFlags(), setting or clearing the DITHER_FLAG bit
283     * Dithering affects how colors that are higher precision than the device
284     * are down-sampled. No dithering is generally faster, but higher precision
285     * colors are just truncated down (e.g. 8888 -> 565). Dithering tries to
286     * distribute the error inherent in this process, to reduce the visual
287     * artifacts.
288     *
289     * @param dither true to set the dithering bit in flags, false to clear it
290     */
291    public native void setDither(boolean dither);
292
293    /**
294     * Helper for getFlags(), returning true if LINEAR_TEXT_FLAG bit is set
295     *
296     * @return true if the lineartext bit is set in the paint's flags
297     */
298    public final boolean isLinearText() {
299        return (getFlags() & LINEAR_TEXT_FLAG) != 0;
300    }
301
302    /**
303     * Helper for setFlags(), setting or clearing the LINEAR_TEXT_FLAG bit
304     *
305     * @param linearText true to set the linearText bit in the paint's flags,
306     *                   false to clear it.
307     */
308    public native void setLinearText(boolean linearText);
309
310    /**
311     * Helper for getFlags(), returning true if SUBPIXEL_TEXT_FLAG bit is set
312     *
313     * @return true if the subpixel bit is set in the paint's flags
314     */
315    public final boolean isSubpixelText() {
316        return (getFlags() & SUBPIXEL_TEXT_FLAG) != 0;
317    }
318
319    /**
320     * Helper for setFlags(), setting or clearing the SUBPIXEL_TEXT_FLAG bit
321     *
322     * @param subpixelText true to set the subpixelText bit in the paint's
323     *                     flags, false to clear it.
324     */
325    public native void setSubpixelText(boolean subpixelText);
326
327    /**
328     * Helper for getFlags(), returning true if UNDERLINE_TEXT_FLAG bit is set
329     *
330     * @return true if the underlineText bit is set in the paint's flags.
331     */
332    public final boolean isUnderlineText() {
333        return (getFlags() & UNDERLINE_TEXT_FLAG) != 0;
334    }
335
336    /**
337     * Helper for setFlags(), setting or clearing the UNDERLINE_TEXT_FLAG bit
338     *
339     * @param underlineText true to set the underlineText bit in the paint's
340     *                      flags, false to clear it.
341     */
342    public native void setUnderlineText(boolean underlineText);
343
344    /**
345     * Helper for getFlags(), returning true if STRIKE_THRU_TEXT_FLAG bit is set
346     *
347     * @return true if the strikeThruText bit is set in the paint's flags.
348     */
349    public final boolean isStrikeThruText() {
350        return (getFlags() & STRIKE_THRU_TEXT_FLAG) != 0;
351    }
352
353    /**
354     * Helper for setFlags(), setting or clearing the STRIKE_THRU_TEXT_FLAG bit
355     *
356     * @param strikeThruText true to set the strikeThruText bit in the paint's
357     *                       flags, false to clear it.
358     */
359    public native void setStrikeThruText(boolean strikeThruText);
360
361    /**
362     * Helper for getFlags(), returning true if FAKE_BOLD_TEXT_FLAG bit is set
363     *
364     * @return true if the fakeBoldText bit is set in the paint's flags.
365     */
366    public final boolean isFakeBoldText() {
367        return (getFlags() & FAKE_BOLD_TEXT_FLAG) != 0;
368    }
369
370    /**
371     * Helper for setFlags(), setting or clearing the STRIKE_THRU_TEXT_FLAG bit
372     *
373     * @param fakeBoldText true to set the fakeBoldText bit in the paint's
374     *                     flags, false to clear it.
375     */
376    public native void setFakeBoldText(boolean fakeBoldText);
377
378    /**
379     * Whether or not the bitmap filter is activated.
380     * Filtering affects the sampling of bitmaps when they are transformed.
381     * Filtering does not affect how the colors in the bitmap are converted into
382     * device pixels. That is dependent on dithering and xfermodes.
383     *
384     * @see #setFilterBitmap(boolean) setFilterBitmap()
385     */
386    public final boolean isFilterBitmap() {
387        return (getFlags() & FILTER_BITMAP_FLAG) != 0;
388    }
389
390    /**
391     * Helper for setFlags(), setting or clearing the FILTER_BITMAP_FLAG bit.
392     * Filtering affects the sampling of bitmaps when they are transformed.
393     * Filtering does not affect how the colors in the bitmap are converted into
394     * device pixels. That is dependent on dithering and xfermodes.
395     *
396     * @param filter true to set the FILTER_BITMAP_FLAG bit in the paint's
397     *               flags, false to clear it.
398     */
399    public native void setFilterBitmap(boolean filter);
400
401    /**
402     * Return the paint's style, used for controlling how primitives'
403     * geometries are interpreted (except for drawBitmap, which always assumes
404     * FILL_STYLE).
405     *
406     * @return the paint's style setting (Fill, Stroke, StrokeAndFill)
407     */
408    public Style getStyle() {
409        return sStyleArray[native_getStyle(mNativePaint)];
410    }
411
412    /**
413     * Set the paint's style, used for controlling how primitives'
414     * geometries are interpreted (except for drawBitmap, which always assumes
415     * Fill).
416     *
417     * @param style The new style to set in the paint
418     */
419    public void setStyle(Style style) {
420        native_setStyle(mNativePaint, style.nativeInt);
421    }
422
423    /**
424     * Return the paint's color. Note that the color is a 32bit value
425     * containing alpha as well as r,g,b. This 32bit value is not premultiplied,
426     * meaning that its alpha can be any value, regardless of the values of
427     * r,g,b. See the Color class for more details.
428     *
429     * @return the paint's color (and alpha).
430     */
431    public native int getColor();
432
433    /**
434     * Set the paint's color. Note that the color is an int containing alpha
435     * as well as r,g,b. This 32bit value is not premultiplied, meaning that
436     * its alpha can be any value, regardless of the values of r,g,b.
437     * See the Color class for more details.
438     *
439     * @param color The new color (including alpha) to set in the paint.
440     */
441    public native void setColor(int color);
442
443    /**
444     * Helper to getColor() that just returns the color's alpha value. This is
445     * the same as calling getColor() >>> 24. It always returns a value between
446     * 0 (completely transparent) and 255 (completely opaque).
447     *
448     * @return the alpha component of the paint's color.
449     */
450    public native int getAlpha();
451
452    /**
453     * Helper to setColor(), that only assigns the color's alpha value,
454     * leaving its r,g,b values unchanged. Results are undefined if the alpha
455     * value is outside of the range [0..255]
456     *
457     * @param a set the alpha component [0..255] of the paint's color.
458     */
459    public native void setAlpha(int a);
460
461    /**
462     * Helper to setColor(), that takes a,r,g,b and constructs the color int
463     *
464     * @param a The new alpha component (0..255) of the paint's color.
465     * @param r The new red component (0..255) of the paint's color.
466     * @param g The new green component (0..255) of the paint's color.
467     * @param b The new blue component (0..255) of the paint's color.
468     */
469    public void setARGB(int a, int r, int g, int b) {
470        setColor((a << 24) | (r << 16) | (g << 8) | b);
471    }
472
473    /**
474     * Return the width for stroking.
475     * <p />
476     * A value of 0 strokes in hairline mode.
477     * Hairlines always draws a single pixel independent of the canva's matrix.
478     *
479     * @return the paint's stroke width, used whenever the paint's style is
480     *         Stroke or StrokeAndFill.
481     */
482    public native float getStrokeWidth();
483
484    /**
485     * Set the width for stroking.
486     * Pass 0 to stroke in hairline mode.
487     * Hairlines always draws a single pixel independent of the canva's matrix.
488     *
489     * @param width set the paint's stroke width, used whenever the paint's
490     *              style is Stroke or StrokeAndFill.
491     */
492    public native void setStrokeWidth(float width);
493
494    /**
495     * Return the paint's stroke miter value. Used to control the behavior
496     * of miter joins when the joins angle is sharp.
497     *
498     * @return the paint's miter limit, used whenever the paint's style is
499     *         Stroke or StrokeAndFill.
500     */
501    public native float getStrokeMiter();
502
503    /**
504     * Set the paint's stroke miter value. This is used to control the behavior
505     * of miter joins when the joins angle is sharp. This value must be >= 0.
506     *
507     * @param miter set the miter limit on the paint, used whenever the paint's
508     *              style is Stroke or StrokeAndFill.
509     */
510    public native void setStrokeMiter(float miter);
511
512    /**
513     * Return the paint's Cap, controlling how the start and end of stroked
514     * lines and paths are treated.
515     *
516     * @return the line cap style for the paint, used whenever the paint's
517     *         style is Stroke or StrokeAndFill.
518     */
519    public Cap getStrokeCap() {
520        return sCapArray[native_getStrokeCap(mNativePaint)];
521    }
522
523    /**
524     * Set the paint's Cap.
525     *
526     * @param cap set the paint's line cap style, used whenever the paint's
527     *            style is Stroke or StrokeAndFill.
528     */
529    public void setStrokeCap(Cap cap) {
530        native_setStrokeCap(mNativePaint, cap.nativeInt);
531    }
532
533    /**
534     * Return the paint's stroke join type.
535     *
536     * @return the paint's Join.
537     */
538    public Join getStrokeJoin() {
539        return sJoinArray[native_getStrokeJoin(mNativePaint)];
540    }
541
542    /**
543     * Set the paint's Join.
544     *
545     * @param join set the paint's Join, used whenever the paint's style is
546     *             Stroke or StrokeAndFill.
547     */
548    public void setStrokeJoin(Join join) {
549        native_setStrokeJoin(mNativePaint, join.nativeInt);
550    }
551
552    /**
553     * Applies any/all effects (patheffect, stroking) to src, returning the
554     * result in dst. The result is that drawing src with this paint will be
555     * the same as drawing dst with a default paint (at least from the
556     * geometric perspective).
557     *
558     * @param src input path
559     * @param dst output path (may be the same as src)
560     * @return    true if the path should be filled, or false if it should be
561     *                 drawn with a hairline (width == 0)
562     */
563    public boolean getFillPath(Path src, Path dst) {
564        return native_getFillPath(mNativePaint, src.ni(), dst.ni());
565    }
566
567    /**
568     * Get the paint's shader object.
569     *
570     * @return the paint's shader (or null)
571     */
572    public Shader getShader() {
573        return mShader;
574    }
575
576    /**
577     * Set or clear the shader object.
578     * <p />
579     * Pass null to clear any previous shader.
580     * As a convenience, the parameter passed is also returned.
581     *
582     * @param shader May be null. the new shader to be installed in the paint
583     * @return       shader
584     */
585    public Shader setShader(Shader shader) {
586        int shaderNative = 0;
587        if (shader != null)
588            shaderNative = shader.native_instance;
589        native_setShader(mNativePaint, shaderNative);
590        mShader = shader;
591        return shader;
592    }
593
594    /**
595     * Get the paint's colorfilter (maybe be null).
596     *
597     * @return the paint's colorfilter (maybe be null)
598     */
599    public ColorFilter getColorFilter() {
600        return mColorFilter;
601    }
602
603    /**
604     * Set or clear the paint's colorfilter, returning the parameter.
605     *
606     * @param filter May be null. The new filter to be installed in the paint
607     * @return       filter
608     */
609    public ColorFilter setColorFilter(ColorFilter filter) {
610        int filterNative = 0;
611        if (filter != null)
612            filterNative = filter.native_instance;
613        native_setColorFilter(mNativePaint, filterNative);
614        mColorFilter = filter;
615        return filter;
616    }
617
618    /**
619     * Get the paint's xfermode object.
620     *
621     * @return the paint's xfermode (or null)
622     */
623    public Xfermode getXfermode() {
624        return mXfermode;
625    }
626
627    /**
628     * Set or clear the xfermode object.
629     * <p />
630     * Pass null to clear any previous xfermode.
631     * As a convenience, the parameter passed is also returned.
632     *
633     * @param xfermode May be null. The xfermode to be installed in the paint
634     * @return         xfermode
635     */
636    public Xfermode setXfermode(Xfermode xfermode) {
637        int xfermodeNative = 0;
638        if (xfermode != null)
639            xfermodeNative = xfermode.native_instance;
640        native_setXfermode(mNativePaint, xfermodeNative);
641        mXfermode = xfermode;
642        return xfermode;
643    }
644
645    /**
646     * Get the paint's patheffect object.
647     *
648     * @return the paint's patheffect (or null)
649     */
650    public PathEffect getPathEffect() {
651        return mPathEffect;
652    }
653
654    /**
655     * Set or clear the patheffect object.
656     * <p />
657     * Pass null to clear any previous patheffect.
658     * As a convenience, the parameter passed is also returned.
659     *
660     * @param effect May be null. The patheffect to be installed in the paint
661     * @return       effect
662     */
663    public PathEffect setPathEffect(PathEffect effect) {
664        int effectNative = 0;
665        if (effect != null) {
666            effectNative = effect.native_instance;
667        }
668        native_setPathEffect(mNativePaint, effectNative);
669        mPathEffect = effect;
670        return effect;
671    }
672
673    /**
674     * Get the paint's maskfilter object.
675     *
676     * @return the paint's maskfilter (or null)
677     */
678    public MaskFilter getMaskFilter() {
679        return mMaskFilter;
680    }
681
682    /**
683     * Set or clear the maskfilter object.
684     * <p />
685     * Pass null to clear any previous maskfilter.
686     * As a convenience, the parameter passed is also returned.
687     *
688     * @param maskfilter May be null. The maskfilter to be installed in the
689     *                   paint
690     * @return           maskfilter
691     */
692    public MaskFilter setMaskFilter(MaskFilter maskfilter) {
693        int maskfilterNative = 0;
694        if (maskfilter != null) {
695            maskfilterNative = maskfilter.native_instance;
696        }
697        native_setMaskFilter(mNativePaint, maskfilterNative);
698        mMaskFilter = maskfilter;
699        return maskfilter;
700    }
701
702    /**
703     * Get the paint's typeface object.
704     * <p />
705     * The typeface object identifies which font to use when drawing or
706     * measuring text.
707     *
708     * @return the paint's typeface (or null)
709     */
710    public Typeface getTypeface() {
711        return mTypeface;
712    }
713
714    /**
715     * Set or clear the typeface object.
716     * <p />
717     * Pass null to clear any previous typeface.
718     * As a convenience, the parameter passed is also returned.
719     *
720     * @param typeface May be null. The typeface to be installed in the paint
721     * @return         typeface
722     */
723    public Typeface setTypeface(Typeface typeface) {
724        int typefaceNative = 0;
725        if (typeface != null) {
726            typefaceNative = typeface.native_instance;
727        }
728        native_setTypeface(mNativePaint, typefaceNative);
729        mTypeface = typeface;
730        return typeface;
731    }
732
733    /**
734     * Get the paint's rasterizer (or null).
735     * <p />
736     * The raster controls/modifies how paths/text are turned into alpha masks.
737     *
738     * @return         the paint's rasterizer (or null)
739     */
740    public Rasterizer getRasterizer() {
741        return mRasterizer;
742    }
743
744    /**
745     * Set or clear the rasterizer object.
746     * <p />
747     * Pass null to clear any previous rasterizer.
748     * As a convenience, the parameter passed is also returned.
749     *
750     * @param rasterizer May be null. The new rasterizer to be installed in
751     *                   the paint.
752     * @return           rasterizer
753     */
754    public Rasterizer setRasterizer(Rasterizer rasterizer) {
755        int rasterizerNative = 0;
756        if (rasterizer != null) {
757            rasterizerNative = rasterizer.native_instance;
758        }
759        native_setRasterizer(mNativePaint, rasterizerNative);
760        mRasterizer = rasterizer;
761        return rasterizer;
762    }
763
764    /**
765     * Temporary API to expose layer drawing. This draws a shadow layer below
766     * the main layer, with the specified offset and color, and blur radius.
767     * If radius is 0, then the shadow layer is removed.
768     */
769    public native void setShadowLayer(float radius, float dx, float dy,
770                                      int color);
771
772    /**
773     * Temporary API to clear the shadow layer.
774     */
775    public void clearShadowLayer() {
776        setShadowLayer(0, 0, 0, 0);
777    }
778
779    /**
780     * Return the paint's Align value for drawing text. This controls how the
781     * text is positioned relative to its origin. LEFT align means that all of
782     * the text will be drawn to the right of its origin (i.e. the origin
783     * specifieds the LEFT edge of the text) and so on.
784     *
785     * @return the paint's Align value for drawing text.
786     */
787    public Align getTextAlign() {
788        return sAlignArray[native_getTextAlign(mNativePaint)];
789    }
790
791    /**
792     * Set the paint's text alignment. This controls how the
793     * text is positioned relative to its origin. LEFT align means that all of
794     * the text will be drawn to the right of its origin (i.e. the origin
795     * specifieds the LEFT edge of the text) and so on.
796     *
797     * @param align set the paint's Align value for drawing text.
798     */
799    public void setTextAlign(Align align) {
800        native_setTextAlign(mNativePaint, align.nativeInt);
801    }
802
803    /**
804     * Return the paint's text size.
805     *
806     * @return the paint's text size.
807     */
808    public native float getTextSize();
809
810    /**
811     * Set the paint's text size. This value must be > 0
812     *
813     * @param textSize set the paint's text size.
814     */
815    public native void setTextSize(float textSize);
816
817    /**
818     * Return the paint's horizontal scale factor for text. The default value
819     * is 1.0.
820     *
821     * @return the paint's scale factor in X for drawing/measuring text
822     */
823    public native float getTextScaleX();
824
825    /**
826     * Set the paint's horizontal scale factor for text. The default value
827     * is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
828     * stretch the text narrower.
829     *
830     * @param scaleX set the paint's scale in X for drawing/measuring text.
831     */
832    public native void setTextScaleX(float scaleX);
833
834    /**
835     * Return the paint's horizontal skew factor for text. The default value
836     * is 0.
837     *
838     * @return         the paint's skew factor in X for drawing text.
839     */
840    public native float getTextSkewX();
841
842    /**
843     * Set the paint's horizontal skew factor for text. The default value
844     * is 0. For approximating oblique text, use values around -0.25.
845     *
846     * @param skewX set the paint's skew factor in X for drawing text.
847     */
848    public native void setTextSkewX(float skewX);
849
850    /**
851     * Return the distance above (negative) the baseline (ascent) based on the
852     * current typeface and text size.
853     *
854     * @return the distance above (negative) the baseline (ascent) based on the
855     *         current typeface and text size.
856     */
857    public native float ascent();
858
859    /**
860     * Return the distance below (positive) the baseline (descent) based on the
861     * current typeface and text size.
862     *
863     * @return the distance below (positive) the baseline (descent) based on
864     *         the current typeface and text size.
865     */
866    public native float descent();
867
868    /**
869     * Class that describes the various metrics for a font at a given text size.
870     * Remember, Y values increase going down, so those values will be positive,
871     * and values that measure distances going up will be negative. This class
872     * is returned by getFontMetrics().
873     */
874    public static class FontMetrics {
875        /**
876         * The maximum distance above the baseline for the tallest glyph in
877         * the font at a given text size.
878         */
879        public float   top;
880        /**
881         * The recommended distance above the baseline for singled spaced text.
882         */
883        public float   ascent;
884        /**
885         * The recommended distance below the baseline for singled spaced text.
886         */
887        public float   descent;
888        /**
889         * The maximum distance below the baseline for the lowest glyph in
890         * the font at a given text size.
891         */
892        public float   bottom;
893        /**
894         * The recommended additional space to add between lines of text.
895         */
896        public float   leading;
897    }
898
899    /**
900     * Return the font's recommended interline spacing, given the Paint's
901     * settings for typeface, textSize, etc. If metrics is not null, return the
902     * fontmetric values in it.
903     *
904     * @param metrics If this object is not null, its fields are filled with
905     *                the appropriate values given the paint's text attributes.
906     * @return the font's recommended interline spacing.
907     */
908    public native float getFontMetrics(FontMetrics metrics);
909
910    /**
911     * Allocates a new FontMetrics object, and then calls getFontMetrics(fm)
912     * with it, returning the object.
913     */
914    public FontMetrics getFontMetrics() {
915        FontMetrics fm = new FontMetrics();
916        getFontMetrics(fm);
917        return fm;
918    }
919
920    /**
921     * Convenience method for callers that want to have FontMetrics values as
922     * integers.
923     */
924    public static class FontMetricsInt {
925        public int   top;
926        public int   ascent;
927        public int   descent;
928        public int   bottom;
929        public int   leading;
930
931        @Override public String toString() {
932            return "FontMetricsInt: top=" + top + " ascent=" + ascent +
933                    " descent=" + descent + " bottom=" + bottom +
934                    " leading=" + leading;
935        }
936    }
937
938    /**
939     * Return the font's interline spacing, given the Paint's settings for
940     * typeface, textSize, etc. If metrics is not null, return the fontmetric
941     * values in it. Note: all values have been converted to integers from
942     * floats, in such a way has to make the answers useful for both spacing
943     * and clipping. If you want more control over the rounding, call
944     * getFontMetrics().
945     *
946     * @return the font's interline spacing.
947     */
948    public native int getFontMetricsInt(FontMetricsInt fmi);
949
950    public FontMetricsInt getFontMetricsInt() {
951        FontMetricsInt fm = new FontMetricsInt();
952        getFontMetricsInt(fm);
953        return fm;
954    }
955
956    /**
957     * Return the recommend line spacing based on the current typeface and
958     * text size.
959     *
960     * @return  recommend line spacing based on the current typeface and
961     *          text size.
962     */
963    public float getFontSpacing() {
964        return getFontMetrics(null);
965    }
966
967    /**
968     * Return the width of the text.
969     *
970     * @param text  The text to measure
971     * @param index The index of the first character to start measuring
972     * @param count THe number of characters to measure, beginning with start
973     * @return      The width of the text
974     */
975    public native float measureText(char[] text, int index, int count);
976
977    /**
978     * Return the width of the text.
979     *
980     * @param text  The text to measure
981     * @param start The index of the first character to start measuring
982     * @param end   1 beyond the index of the last character to measure
983     * @return      The width of the text
984     */
985    public native float measureText(String text, int start, int end);
986
987    /**
988     * Return the width of the text.
989     *
990     * @param text  The text to measure
991     * @return      The width of the text
992     */
993    public native float measureText(String text);
994
995    /**
996     * Return the width of the text.
997     *
998     * @param text  The text to measure
999     * @param start The index of the first character to start measuring
1000     * @param end   1 beyond the index of the last character to measure
1001     * @return      The width of the text
1002     */
1003    public float measureText(CharSequence text, int start, int end) {
1004        if (text instanceof String) {
1005            return measureText((String)text, start, end);
1006        }
1007        if (text instanceof SpannedString ||
1008            text instanceof SpannableString) {
1009            return measureText(text.toString(), start, end);
1010        }
1011        if (text instanceof GraphicsOperations) {
1012            return ((GraphicsOperations)text).measureText(start, end, this);
1013        }
1014
1015        char[] buf = TemporaryBuffer.obtain(end - start);
1016    	TextUtils.getChars(text, start, end, buf, 0);
1017    	float result = measureText(buf, 0, end - start);
1018        TemporaryBuffer.recycle(buf);
1019    	return result;
1020    }
1021
1022    /**
1023     * Measure the text, stopping early if the measured width exceeds maxWidth.
1024     * Return the number of chars that were measured, and if measuredWidth is
1025     * not null, return in it the actual width measured.
1026     *
1027     * @param text  The text to measure
1028     * @param index The offset into text to begin measuring at
1029     * @param count The number of maximum number of entries to measure. If count
1030     *              is negative, then the characters before index are measured
1031     *              in reverse order. This allows for measuring the end of
1032     *              string.
1033     * @param maxWidth The maximum width to accumulate.
1034     * @param measuredWidth Optional. If not null, returns the actual width
1035     *                     measured.
1036     * @return The number of chars that were measured. Will always be <=
1037     *         abs(count).
1038     */
1039    public native int breakText(char[] text, int index, int count,
1040                                float maxWidth, float[] measuredWidth);
1041
1042    /**
1043     * Measure the text, stopping early if the measured width exceeds maxWidth.
1044     * Return the number of chars that were measured, and if measuredWidth is
1045     * not null, return in it the actual width measured.
1046     *
1047     * @param text  The text to measure
1048     * @param start The offset into text to begin measuring at
1049     * @param end   The end of the text slice to measure.
1050     * @param measureForwards If true, measure forwards, starting at start.
1051     *                        Otherwise, measure backwards, starting with end.
1052     * @param maxWidth The maximum width to accumulate.
1053     * @param measuredWidth Optional. If not null, returns the actual width
1054     *                     measured.
1055     * @return The number of chars that were measured. Will always be <=
1056     *         abs(end - start).
1057     */
1058    public int breakText(CharSequence text, int start, int end,
1059                         boolean measureForwards,
1060                         float maxWidth, float[] measuredWidth) {
1061        if (start == 0 && text instanceof String && end == text.length()) {
1062            return breakText((String) text, measureForwards, maxWidth,
1063                             measuredWidth);
1064        }
1065
1066        char[] buf = TemporaryBuffer.obtain(end - start);
1067        int result;
1068
1069        TextUtils.getChars(text, start, end, buf, 0);
1070
1071        if (measureForwards) {
1072            result = breakText(buf, 0, end - start, maxWidth, measuredWidth);
1073        } else {
1074            result = breakText(buf, 0, -(end - start), maxWidth, measuredWidth);
1075        }
1076
1077        TemporaryBuffer.recycle(buf);
1078        return result;
1079    }
1080
1081    /**
1082     * Measure the text, stopping early if the measured width exceeds maxWidth.
1083     * Return the number of chars that were measured, and if measuredWidth is
1084     * not null, return in it the actual width measured.
1085     *
1086     * @param text  The text to measure
1087     * @param measureForwards If true, measure forwards, starting at index.
1088     *                        Otherwise, measure backwards, starting with the
1089     *                        last character in the string.
1090     * @param maxWidth The maximum width to accumulate.
1091     * @param measuredWidth Optional. If not null, returns the actual width
1092     *                     measured.
1093     * @return The number of chars that were measured. Will always be <=
1094     *         abs(count).
1095     */
1096    public native int breakText(String text, boolean measureForwards,
1097                                float maxWidth, float[] measuredWidth);
1098
1099    /**
1100     * Return the advance widths for the characters in the string.
1101     *
1102     * @param text     The text to measure
1103     * @param index    The index of the first char to to measure
1104     * @param count    The number of chars starting with index to measure
1105     * @param widths   array to receive the advance widths of the characters.
1106     *                 Must be at least a large as count.
1107     * @return         the actual number of widths returned.
1108     */
1109    public int getTextWidths(char[] text, int index, int count,
1110                             float[] widths) {
1111        if ((index | count) < 0 || index + count > text.length
1112                || count > widths.length) {
1113            throw new ArrayIndexOutOfBoundsException();
1114        }
1115        return native_getTextWidths(mNativePaint, text, index, count, widths);
1116    }
1117
1118    /**
1119     * Return the advance widths for the characters in the string.
1120     *
1121     * @param text     The text to measure
1122     * @param start    The index of the first char to to measure
1123     * @param end      The end of the text slice to measure
1124     * @param widths   array to receive the advance widths of the characters.
1125     *                 Must be at least a large as (end - start).
1126     * @return         the actual number of widths returned.
1127     */
1128    public int getTextWidths(CharSequence text, int start, int end,
1129                             float[] widths) {
1130        if (text instanceof String) {
1131            return getTextWidths((String) text, start, end, widths);
1132        }
1133        if (text instanceof SpannedString ||
1134            text instanceof SpannableString) {
1135            return getTextWidths(text.toString(), start, end, widths);
1136        }
1137        if (text instanceof GraphicsOperations) {
1138            return ((GraphicsOperations) text).getTextWidths(start, end,
1139                                                                 widths, this);
1140        }
1141
1142        char[] buf = TemporaryBuffer.obtain(end - start);
1143    	TextUtils.getChars(text, start, end, buf, 0);
1144    	int result = getTextWidths(buf, 0, end - start, widths);
1145        TemporaryBuffer.recycle(buf);
1146    	return result;
1147    }
1148
1149    /**
1150     * Return the advance widths for the characters in the string.
1151     *
1152     * @param text   The text to measure
1153     * @param start  The index of the first char to to measure
1154     * @param end    The end of the text slice to measure
1155     * @param widths array to receive the advance widths of the characters.
1156     *               Must be at least a large as the text.
1157     * @return       the number of unichars in the specified text.
1158     */
1159    public int getTextWidths(String text, int start, int end, float[] widths) {
1160        if ((start | end | (end - start) | (text.length() - end)) < 0) {
1161            throw new IndexOutOfBoundsException();
1162        }
1163        if (end - start > widths.length) {
1164            throw new ArrayIndexOutOfBoundsException();
1165        }
1166        return native_getTextWidths(mNativePaint, text, start, end, widths);
1167    }
1168
1169    /**
1170     * Return the advance widths for the characters in the string.
1171     *
1172     * @param text   The text to measure
1173     * @param widths array to receive the advance widths of the characters.
1174     *               Must be at least a large as the text.
1175     * @return       the number of unichars in the specified text.
1176     */
1177    public int getTextWidths(String text, float[] widths) {
1178        return getTextWidths(text, 0, text.length(), widths);
1179    }
1180
1181    /**
1182     * Return the path (outline) for the specified text.
1183     * Note: just like Canvas.drawText, this will respect the Align setting in
1184     * the paint.
1185     *
1186     * @param text     The text to retrieve the path from
1187     * @param index    The index of the first character in text
1188     * @param count    The number of characterss starting with index
1189     * @param x        The x coordinate of the text's origin
1190     * @param y        The y coordinate of the text's origin
1191     * @param path     The path to receive the data describing the text. Must
1192     *                 be allocated by the caller.
1193     */
1194    public void getTextPath(char[] text, int index, int count,
1195                            float x, float y, Path path) {
1196        if ((index | count) < 0 || index + count > text.length) {
1197            throw new ArrayIndexOutOfBoundsException();
1198        }
1199        native_getTextPath(mNativePaint, text, index, count, x, y, path.ni());
1200    }
1201
1202    /**
1203     * Return the path (outline) for the specified text.
1204     * Note: just like Canvas.drawText, this will respect the Align setting
1205     * in the paint.
1206     *
1207     * @param text  The text to retrieve the path from
1208     * @param start The first character in the text
1209     * @param end   1 past the last charcter in the text
1210     * @param x     The x coordinate of the text's origin
1211     * @param y     The y coordinate of the text's origin
1212     * @param path  The path to receive the data describing the text. Must
1213     *              be allocated by the caller.
1214     */
1215    public void getTextPath(String text, int start, int end,
1216                            float x, float y, Path path) {
1217        if ((start | end | (end - start) | (text.length() - end)) < 0) {
1218            throw new IndexOutOfBoundsException();
1219        }
1220        native_getTextPath(mNativePaint, text, start, end, x, y, path.ni());
1221    }
1222
1223    /**
1224     * Return in bounds (allocated by the caller) the smallest rectangle that
1225     * encloses all of the characters, with an implied origin at (0,0).
1226     *
1227     * @param text  String to measure and return its bounds
1228     * @param start Index of the first char in the string to measure
1229     * @param end   1 past the last char in the string measure
1230     * @param bounds Returns the unioned bounds of all the text. Must be
1231     *               allocated by the caller.
1232     */
1233    public void getTextBounds(String text, int start, int end, Rect bounds) {
1234        if ((start | end | (end - start) | (text.length() - end)) < 0) {
1235            throw new IndexOutOfBoundsException();
1236        }
1237        if (bounds == null) {
1238            throw new NullPointerException("need bounds Rect");
1239        }
1240        nativeGetStringBounds(mNativePaint, text, start, end, bounds);
1241    }
1242
1243    /**
1244     * Return in bounds (allocated by the caller) the smallest rectangle that
1245     * encloses all of the characters, with an implied origin at (0,0).
1246     *
1247     * @param text  Array of chars to measure and return their unioned bounds
1248     * @param index Index of the first char in the array to measure
1249     * @param count The number of chars, beginning at index, to measure
1250     * @param bounds Returns the unioned bounds of all the text. Must be
1251     *               allocated by the caller.
1252     */
1253    public void getTextBounds(char[] text, int index, int count, Rect bounds) {
1254        if ((index | count) < 0 || index + count > text.length) {
1255            throw new ArrayIndexOutOfBoundsException();
1256        }
1257        if (bounds == null) {
1258            throw new NullPointerException("need bounds Rect");
1259        }
1260        nativeGetCharArrayBounds(mNativePaint, text, index, count, bounds);
1261    }
1262
1263    protected void finalize() throws Throwable {
1264        finalizer(mNativePaint);
1265    }
1266
1267    private static native int native_init();
1268    private static native int native_initWithPaint(int paint);
1269    private static native void native_reset(int native_object);
1270    private static native void native_set(int native_dst, int native_src);
1271    private static native int native_getStyle(int native_object);
1272    private static native void native_setStyle(int native_object, int style);
1273    private static native int native_getStrokeCap(int native_object);
1274    private static native void native_setStrokeCap(int native_object, int cap);
1275    private static native int native_getStrokeJoin(int native_object);
1276    private static native void native_setStrokeJoin(int native_object,
1277                                                    int join);
1278    private static native boolean native_getFillPath(int native_object,
1279                                                     int src, int dst);
1280    private static native int native_setShader(int native_object, int shader);
1281    private static native int native_setColorFilter(int native_object,
1282                                                    int filter);
1283    private static native int native_setXfermode(int native_object,
1284                                                 int xfermode);
1285    private static native int native_setPathEffect(int native_object,
1286                                                   int effect);
1287    private static native int native_setMaskFilter(int native_object,
1288                                                   int maskfilter);
1289    private static native int native_setTypeface(int native_object,
1290                                                 int typeface);
1291    private static native int native_setRasterizer(int native_object,
1292                                                   int rasterizer);
1293
1294    private static native int native_getTextAlign(int native_object);
1295    private static native void native_setTextAlign(int native_object,
1296                                                   int align);
1297
1298    private static native float native_getFontMetrics(int native_paint,
1299                                                      FontMetrics metrics);
1300    private static native int native_getTextWidths(int native_object,
1301                            char[] text, int index, int count, float[] widths);
1302    private static native int native_getTextWidths(int native_object,
1303                            String text, int start, int end, float[] widths);
1304    private static native void native_getTextPath(int native_object,
1305                char[] text, int index, int count, float x, float y, int path);
1306    private static native void native_getTextPath(int native_object,
1307                String text, int start, int end, float x, float y, int path);
1308    private static native void nativeGetStringBounds(int nativePaint,
1309                                String text, int start, int end, Rect bounds);
1310    private static native void nativeGetCharArrayBounds(int nativePaint,
1311                                char[] text, int index, int count, Rect bounds);
1312    private static native void finalizer(int nativePaint);
1313}
1314
1315