Lesson 149. Drawing. text

Lesson 149. Drawing. text


In this lesson:

– working with text

In the past lessons, we have already displayed text, adjusted the alignment for it, used path to specify the line of text. Let’s see what other operations are available when working with text.

sizing

There are several methods that allow you to define text sizes.

To begin with, let’s define the width of the entire text and each character separately.

Let’s create a project:

Project name: P1491_CanvasText
Build Target: Android 2.3.3
Application name: CanvasText
Package name: en.startandroid.develop.p1491canvastext
Create Activity: MainActivity

MainActivity.java:

package ru.startandroid.develop.p1491canvastext;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new DrawView(this));
  }

  class DrawView extends View {

    Paint fontPaint;
    Paint redPaint;
    String text = "Test width text";
    int fontSize = 100;
    float[] widths;
    float width;

    public DrawView(Context context) {
      super(context);
      redPaint = new Paint();
      redPaint.setColor(Color.RED);

      fontPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      fontPaint.setTextSize(fontSize);
      fontPaint.setStyle(Paint.Style.STROKE);

      // ширина текста
      width = fontPaint.measureText(text);

      // посимвольная ширина 
      widths = new float[text.length()];
      fontPaint.getTextWidths(text, widths);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      canvas.translate(50, 250);

      // вывод текста
      canvas.drawText(text, 0, 0, fontPaint);

      // линия шириной в текст
      canvas.drawLine(0, 0, width, 0, fontPaint);

      // посимвольные красные точки 
      canvas.drawCircle(0, 0, 3, redPaint);
      for (float w : widths) {
        canvas.translate(w, 0);
        canvas.drawCircle(0, 0, 3, redPaint);
      }
    }
  }

}

In the DrawView constructor, we create and customize fontPaint to be used to output text. Here we calculate text sizes. The measureText method returns the width of the specified text. Save it in variable width. And the getTextWidths method allows you to get an array containing width values ​​for each character of the text. We use an array of widths, the size of which is equal to the number of characters in the text.

OnDraw we draw text. And below the text we draw a line with a width equal to the previously obtained width of the text – width, and using an array of widths we show red dots, marking the width of each character.

result:

Next, consider the breakText method. It will let us know how many characters of text fit into the width we specify.

rewrite the class DrawView:

class DrawView extends View {

    Paint p;
    String text = "Test width text";
    int fontSize = 80;
    int maxWidth = 350;
    float realWidth = 0;
    int cnt = 0;
    String info = "";

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setTextSize(fontSize);

      // кол-во символов и их ширина
      float[] measuredWidth = new float[1];
      cnt = p.breakText(text, true, maxWidth, measuredWidth);
      realWidth = measuredWidth[0];

      info = "cnt = " + cnt + ", realWidth = " + realWidth
          + ", maxWidth = " + maxWidth;

    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      // данные о ширине
      p.setTextSize(24);
      canvas.drawText(info, 50, 50, p);

      // текст
      p.setTextSize(fontSize);
      canvas.drawText(text, 50, 250, p);

      p.setStrokeWidth(10);

      // полоса реальной ширины урезанного текста
      p.setColor(Color.BLUE);
      canvas.drawLine(50, 260, 50 + realWidth, 260, p);

      // полоса лимита
      p.setColor(Color.GREEN);
      canvas.drawLine(50, 270, 50 + maxWidth, 270, p);

    }
  }

In the DrawView constructor, we call the breakText method. At the entrance we pass:

– text
– true, means that we will go forward in the text, starting with the first character. If false, we will go to the end.
– the width that will limit the text
– array to obtain the exact width value

The breakText method returns the number of characters.

That is, we ask the Paint object how many characters of the specified text text fit into the specified width maxWidth. We get the answer in the variable cnt. And in the measuredWidth array the exact width of the cut-in text also gets, for convenience we will save it in variable realWidth.

OnDraw displays the text with the data received, the desired text and two stripes for clarity. The blue bar shows the exact width (realWidth) of the trimmed text, and the green shows the limit (maxWidth) that we set.

result:

maxWidth is 350 for us. The breakText method found that only 9 characters came out of the specified text at 350 px and they will occupy 330 px in width.

The blue bar shows the width of the trimmed text. You can see that there are 9 characters above this bar (including space).

The green bar showed the limit we set – 350.

Among the measurement methods is also the getTextBounds method, which will allow you to get the rectangle that encloses the text.

Fonts, styles

Consider using font types and styles.

rewrite the class DrawView:

class DrawView extends View {

    Paint p;
    String text = "Test width text";
    int fontSize = 60;
    float y = 80;

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setTextSize(fontSize);
      p.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      // обычный текст
      canvas.translate(50, y);
      canvas.drawText(text, 0, 0, p);

      // моноширинный
      canvas.translate(0, y);
      p.setTypeface(Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL));
      canvas.drawText(text, 0, 0, p);

      // с засечками
      canvas.translate(0, y);
      p.setTypeface(Typeface.create(Typeface.SERIF, Typeface.NORMAL));
      canvas.drawText(text, 0, 0, p);

      // обычный жирный 
      canvas.translate(0, y);
      p.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
      canvas.drawText(text, 0, 0, p);

      // обычный жирный курсивный
      canvas.translate(0, y);
      p.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC));
      canvas.drawText(text, 0, 0, p);

      // обычный курсивный
      canvas.translate(0, y);
      p.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC));
      canvas.drawText(text, 0, 0, p);

    }
  }

OnDraw we output the same text using different font types and styles. To do this, we use the setTypeface method, which requires Typeface input. Typeface can be created using the create method, which requires type and style input.

result:

First we use the default font, then we build different combinations

of types:

MONOSPACE is mono, ie the width of all characters is the same

SERIF – serif font

DEFAULT is the default font

and styles:

NORMAL – Normal

BOLD is bold

BOLD_ITALIC – bold italic

ITALIC – italic

In addition to system fonts, you can use your own fonts. Instead, you need to use the other types of the Typeface.create method. For example createFromAsset. Put your font in the assets folder and specify the filename in the createFromAsset method.

Consider some more text formatting methods.

rewrite the class DrawView:

class DrawView extends View {

    Paint p;
    String text = "Test width text";
    int fontSize = 60;
    float y = 80;

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setTextSize(fontSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      // обычный текст
      canvas.translate(50, y);
      canvas.drawText(text, 0, 0, p);

      // растянутый
      canvas.translate(0, y);
      p.setTextScaleX(1.5f);
      canvas.drawText(text, 0, 0, p);
      p.setTextScaleX(1);

      // наклоненный
      canvas.translate(0, y);
      p.setTextSkewX(0.5f);
      canvas.drawText(text, 0, 0, p);
      p.setTextSkewX(0);

      // подчеркнутый
      canvas.translate(0, y);
      p.setUnderlineText(true);
      canvas.drawText(text, 0, 0, p);
      p.setUnderlineText(false);

      // зачеркнутый
      canvas.translate(0, y);
      p.setStrikeThruText(true);
      canvas.drawText(text, 0, 0, p);
      p.setStrikeThruText(false);

    }
  }

setTextScaleX – allows you to stretch / compress text

setTextSkewX – the slope of the text

setUnderlineText – underlined text

setStrikeThruText – crossed out text

result:

the rest

The drawPosText method allows you to scatter character text at various points

rewrite the class DrawView:

class DrawView extends View {

    Paint p;
    String text = "Test text";
    int fontSize = 100;
    float pos[];

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setTextSize(fontSize);

      pos = new float[] { 100, 300, 200, 150, 300, 500, 400, 300, 500,
          250, 600, 350, 700, 400, 800, 200, 900, 500 };

    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);

      canvas.drawPosText(text, pos, p);

    }
  }

In the constructor we create an array of pos. It specifies the coordinates of the points at which the characters of the text will be scattered.

In onDraw, we call drawPosText and pass it the text and an array.

result:

Measurement methods can be used not only in drawing. You can get a Paint object for the regular TextView using the getPaint method, and then call the methods you need. And the setTypeface method (for a font job) in TextView has its own.

In the next lesson:

– we use PathMeasure to work with Path




Discuss in the forum [1 reply]

Leave a Comment