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