As an Android developer, Paint will inevitably be used at some point in your project, so have you thought about what Paint’s main responsibilities will be? Instead, the Paint class holds style and color information about how to draw geometry, text, and bitmaps.

Let’s take a look at what Settings or methods are available for Paint.

Some setter methods for Paint

Because Paint saves a lot of Settings for “brushes,” let’s start by looking at the methods of its setter type to see what items can be set.

infrastructure

  • SetAntiAlias (Boolean) — Anti-aliasing

    Indicates whether anti-aliasing is enabled. Anti-aliasing will make the edges of irregular graphics (circles, text, etc.) look smoother according to a specific algorithm (insert certain pixels so that the edges of irregular graphics don’t look as burr). It is not necessary to turn on anti-aliasing when drawing sharp and angular images (rectangles, bitmaps, etc.).

  • SetStyle (paint.style) — Sets the fill method

    Paint.Style.STROKE

    Paint.Style.FILL

    Paint.Style.FILL_AND_STROKE

  • SetShadowLayer – Draws a shadow at the bottom of the content

    //radius shadow blur //dx dy shadow offset //shadowColorsetShadowLayer(float radius, float dx, float dy, int shadowColor)
    Copy the code

  • SetMaskFilter – Casts a shadow over the content while drawing it

    setMaskFilter(MaskFilter maskfilter)
    Copy the code

    Existing subclasses of MaskFilter:

    BlurMaskFilter(float radius,// Blurmaskfilter.blur Style)// Blur type

    BlurMaskFilter. The Blur. INNER / / add fuzzy images

    BlurMaskFilter. The Blur. NORMAL / / range both inside and outside and fuzzy image

    BlurMaskFilter. The Blur. OUTER / / image space, draw the external fuzzy

    BlurMaskFilter. The Blur. SOLID / / image area is not affected by fuzzy, external draw fuzzy

    EmbossMaskFilter(

    Float [] direction, // An array of three scalars [x, y, z] specifying the direction of the light source

    Float ambient, // Ambient light intensity 0 to 1

    Float specular, // Specular coefficient

    Float blurRadius // Light range

    )

  • SetPathEffect (PathEffect) – The outline effect of drawing graphics (dashed lines, curves, broken lines, wavy lines, etc.)

    Existing subclasses of PathEffect:

    The corners will be rounded

    DiscretePathEffect for random deviation

    DashPathEffect(float[] intervals, float phase) Dashed line

    The intervals specify the format of dashed lines: the elements in the array must be even (at least two), and the intervals must be “dotted, blank, dotted, blank”… In order of

    Phase is the offset of the dotted line

    PathDashPathEffect can specify dashed lines in line segment shape

    SumPathEffect(PathEffect First, PathEffect Second) combination effect, using first and second respectively

    ComposePathEffect(PathEffect outerPE, PathEffect innerPE) combines the effect of drawing with the innerPE. Use the outerPE to change the result of drawing with the innerPE

color

  • SetAlpha — Transparency

  • SetARGB — Sets the color

  • SetColor — Sets the color

  • SetColorFilter (ColorFilter) — sets the ColorFilter

  • SetShader (Shader) – Sets the Shader scheme

    LinearGradient — LinearGradient

    Float x0, float y0, // Linear start

    Float x1, float y1, // linear endpoint

    Int color0, int color1, // start/stop color

    Shader.tilemode tile) // Out of range processing scheme

    Shader.TileMode has the following three types:

    Shader.TileMode.CLAMP continuation of the endpoint color beyond the endpoint

    Shader.tilemode.MIRROR MIRROR mode

    Shader.tilemode.REPEAT REPEAT mode

    RadialGradient — Radiation gradient

    Float centerX, float centerY, //

    Float radius, // Radiation radius

    Int centerColor, int edgeColor, // start and end colors

    TileMode tileMode)

    SweepGradient — Scan gradient

    Float cx, float cy, // scan center

    Int color0, int color1)// start/stop color

    BitmapShader — Bitmap shader

    Bitmap Bitmap,// The Bitmap used for coloring

    Shader.TileMode tileX, // Horizontal out-of-range processing scheme

    Shader.tilemode tileY)// Vertical output range processing scheme

    ComposeShader — Blend shader

    Shader shaderA, // Shader scheme A

    Shader shaderB, // Shader scheme B

    Porterduff.mode Mode)// Overlay Mode of B (later drawn as source image SRC) to A (already drawn as target image DST), which will be described in detail later

Line is related to

  • SetStrokeWidth (float) — Line thickness

  • SetStrokeCap (Paint. Cap) and – line

    Paint.Cap.BUTT flattop, default

    Paint. Cap. ROUND ROUND head

    Paint. Cap. SQUARE, SQUARE head

  • SetStrokeJoin (paint.join) — Inflection point processing

    Paint.Join.MITER sharp corners, default

    Paint. Join. ROUND corner

    Paint. Join. BEVEL boxer

  • SetStrokeMiter (float) – a complement to paint.join.miter, which can be very long and sharp in extreme cases.

The text

  • FakeBoldText (Boolean) — Text in bold

  • SetFontFeatureSettings (String) – CSS styles used to draw text

  • SetLetterSpacing (float) – Character spacing

  • SetLinearText (Boolean) — Turn on linear text identifiers

    On Android, the text is drawn using a bitmap as a single character cache. Since the cache must use a certain amount of space, we can use setLinearText (true) to tell Android that we don’t need such a text cache.

  • SetStrikeThruText (Boolean) — Add the delete line

  • SetTextAlign (paint.align) — Text alignment

    Paint. The Align. LEFT LEFT alignment

    Paint. The Align. CENTER in the middle

    Paint. The Align. RIGHT RIGHT alignment

  • SetTextLocale (Locale) — Sets Locale(Locale. GetDefault uses the default Locale)

  • SetTextScaleX (float) – Horizontal scale factor for text

  • SetTextSize (float Pixel) – Text size

  • SetTextSkewX (float) – horizontal error tangent factor for text

  • SetTypeface (Typeface) – Sets fonts

  • SetUnderlineText (Boolean) — Set the underline

  • SetWordSpacing (float Pixel) – Sets word spacing, defaults to 0

  • SetSubpixelText (Boolean) — true, helps with LCD text display

Bitmap related

  • SetDither (Boolena) – Whether to enable jitter

    The so-called dithering refers to the practice of intentionally inserting noise in the image to make the image more realistic to the naked eye by regularly disturbing the image when drawing the image from a higher color depth (the number of available colors) to a lower color depth area.

  • SetFilterBitmap (Boolean) — Use bilinear filtering to draw bitmaps

    The nearest neighbor interpolation filter is used by default when the image is enlarged and drawn. This algorithm is simple, but it will appear Mosaic phenomenon. If bilinear filtering is turned on, the resulting image will appear smoother.

Draw the overlap

  • setXfermode(Xfermode)

The only subclass of Xfermode is PorterDuffXfermode(porterduff.mode), which is passed in for initialization

  • setBlendMode(BlendMode)

    On the basis of setXfermode, several blending modes are added

    There are two broad categories of composition rules

    Blue is SRC (drawn later) and red is DST (drawn already)

    Alpha synthesis mode:

    Mixed mode:

    BlendMode has several new modes:

Some other methods for Paint

Text size correlation

  • getFontMetrics(FontMetrics)/getFontMetricsInt(FontMetricsInt)

    Get FontMetrics for Paint instead of specific text.

  • getFontSpacing

    Gets the recommended line spacing.

  • getTextBounds(String text, int start, int end, Rect bounds)

    Gets the display (visible) range of text.

  • float measureText(String text)

    Measure the width of text occupied (including visually invisible).

  • getTextWidths(String text, float[] widths)

    Gets the width of each character in the string and fills the result in the parameter widths.

  • int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)

    Measure the width of text with an upper limit on width. If the width of the text exceeds the upper limit, truncate the text near the upper limit.

  • ascent

    Current font and font size under Paint’s ascent.

  • descent

    Descent for Paint under the current font and size.

The cursor associated

  • getRunAdvance

    For a paragraph of text, calculate the x coordinate of the cursor at a character.

  • getOffsetForAdvance

    Given the pixel value of a position, calculate the offset of the character closest to that position in the text (that is, the number of characters closest to the coordinate).

The Path correlation

  • getFillPath(Path src, Path dst)

    By default (line width 0, no PathEffect), the path obtained is the path drawn (drawPath); In other cases, the path is inconsistent with the source path:

  • getTextPath

    Gets the path of the target text.

About FontMetircs

FontMetrics is a relatively specialized tool class that provides several typography values: Ascent, Descent, Top, Bottom, and leading.

There are five lines and a special leading:

  • Top /bottom: Limit the top and bottom range of all glyphs; Except for normal characters, some glyphs are displayed beyond ascent and Descent, while top and Bottom limit the display of all glyphs, including these special glyphs. Since it is for the baseline displacement, top is negative and bottom is positive.

  • Ascent /descent: limits the top and bottom ranges of ordinary characters; A normal character is neither higher than ascent nor lower than descent. Since it is for the displacement of the baseline, ascent is negative and DESCENT is positive.

  • Baseline: text rendering baseline.

  • Leading: set the distance between the top line and the bottom line.

Center text vertically when drawing

When using Canvas to draw text, use the following methods:

DrawText (String text,float x, float y, Paint paint)
Copy the code

But the y-coordinate specified here is the position of the baseline, so if you want the text to be centered vertically based on a y value, you need to move the baseline down appropriately. You can calculate the value to be moved down as follows:

The baseline needs to be offset so that the text center point is at y value //1. Find the center position (must be above the baseline) //2. The center has a displacement value from the baseline (negative because it is above the baseline) //3. // Method 1 does not care what text is drawn, the unified solution is centered, if the drawing content is aAAA, then it will look like: GetFontMetrics (fontMetrics) deltY = (fontMetrics. Ascent + fontMetrics. It's better to center the bounds precisely based on the text."Crazy Coder", 0,"Crazy Coder".length(),rect) deltY = (rect.top + rect.bottom) / 2 /"Crazy Coder",x,y - deltY,paint)
Copy the code

Draw text strictly in line with the X coordinate

When we drawText from drawText, we set the x coordinate, but when we draw, we don’t actually drawText from x, but something like this:

As you can see, the starting point (red dot) is a little before the first letter H. This happens because each character has a left and right margin, and the larger the font, the larger the margin.

The space occupied by the text when drawing itself:

Blue is the space that getTextBounds takes up, and orange is the space that getTextBounds gets.

The horizontal absolute definition can be handled as follows:

paint.getTextBounds("Crazy Coder", 0,"Crazy Coder".length(),rect) deltX = rect.left"Crazy Coder",x - deltX,y,paint)
Copy the code

The processing of line breaks when drawing text

  • StaticLayout

    StaticLayout is not a View or ViewGroup, but a subclass of Android.text. Layout, which is purely for drawing text. StaticLayout supports line breaking, which can either set an upper limit on the width of text to wrap it automatically, or actively wrap it at \n.

    Its construction method:

    StaticLayout(
    CharSequence sourceTextPaint Paint, // Draw the text brush int Width, // Width limit layout. Alignment align, // Text Alignment directionfloatSpacingmult, // Multiple of line spacing, usually 1floatSpacingadd, // Additional value for line spacing, usually 0 Boolean includepad// Whether to add extra space above and below the text to avoid some excessively high characters being drawn out of bounds)Copy the code
  • Paint. BreakText implements mixed text

    The key to using this approach is:

    1. Use breakText to get the count of the number of characters that can be drawn on the line based on the current available width widthMax

    int count = paint.breakText(
    "Crazy Coder Crazy Coder Crazy Coder Crazy Coder..."
    true,
    widthMax,
    cutWidth
    )
    Copy the code

    2. Draw the text on the current line. The start text is index and the end text is index + count

    CurrentY = currentY + Piant.getFontSpace () * (linecount-1)

    canvas.drawText(
    "Crazy Coder Crazy Coder Crazy Coder Crazy Coder..."
    index,
    index + count,
    startX,
    currentY,
    paint
    )
    Copy the code

The resources

  • Hen Coder