Android Canvas DrawText for vertical centering in Chinese

Source: Internet
Author: User
Tags drawtext

Target:

Draws the Chinese character to the center of the target rectangle.

Questions:

Android Canvas drawing, origin in the DrawText is based on baseline, directly to the target rectangle bottom into DrawText, the character position will be lower. Write the code like this:

[Java]View Plaincopy print?
  1. @Override
  2. Public void OnDraw (canvas canvas) {
  3. Rect targetrect = new rect ( 200);
  4. Paint paint = new paint (Paint.anti_alias_flag);
  5. Paint.setstrokewidth (3);
  6. Paint.settextsize (80);
  7. String teststring = "test: ijkjqka:1234";
  8. Paint.setcolor (Color.cyan);
  9. Canvas.drawrect (targetrect, paint);
  10. Paint.setcolor (color.red);
  11. Canvas.drawtext (teststring, Targetrect.left, Targetrect.bottom, paint);
  12. }

Will get ugly results:

Find a solution:

First do your own experiment, set a baseline, and then put the text, and then draw a few lines on the FontMetrics. The FontMetrics is a font pattern, with a float type and an int version, which can be obtained from the paint. Each of its member values is calculated as a baseline, so a negative value is represented above the baseline. Experiment Code:

[Java]View Plaincopy print?
  1. @Override
  2. Public void OnDraw (canvas canvas) {
  3. Paint paint = new paint (Paint.anti_alias_flag);
  4. Paint.setstrokewidth (3);
  5. Paint.settextsize (80);
  6. Fontmetricsint FMI = Paint.getfontmetricsint ();
  7. String teststring = "test: ijkjqka:1234";
  8. Rect bounds1 = new Rect ();
  9. Paint.gettextbounds ("test", 0, 1, BOUNDS1);
  10. Rect bounds2 = new Rect ();
  11. Paint.gettextbounds ("test: Ijk", 0, 6, BOUNDS2);
  12. //Feel free to set a position as baseline
  13. int x = 200;
  14. int y = 400;
  15. //Draw teststring on the baseline
  16. Canvas.drawtext (teststring, x, y, paint);
  17. //BOUNDS1
  18. Paint.setstyle (Style.stroke); //Draw Hollow Rectangle
  19. Canvas.save ();
  20. Canvas.translate (x, y); //Note there are translate here. Gettextbounds The resulting rectangle is also based on the baseline
  21. Paint.setcolor (Color.green);
  22. Canvas.drawrect (BOUNDS1, paint);
  23. Canvas.restore ();
  24. //Bounds2
  25. Canvas.save ();
  26. Paint.setcolor (Color.magenta);
  27. Canvas.translate (x, y);
  28. Canvas.drawrect (bounds2, paint);
  29. Canvas.restore ();
  30. //Baseline
  31. Paint.setcolor (color.red);
  32. Canvas.drawline (x, Y, 1024x768, y, paint);
  33. //Ascent
  34. Paint.setcolor (Color.yellow);
  35. Canvas.drawline (x, Y+fmi.ascent, 1024x768, y+fmi.ascent, paint);
  36. //Descent
  37. Paint.setcolor (Color.Blue);
  38. Canvas.drawline (x, Y+fmi.descent, 1024x768, y+fmi.descent, paint);
  39. //Top
  40. Paint.setcolor (Color.dkgray);
  41. Canvas.drawline (x, Y+fmi.top, 1024x768, y+fmi.top, paint);
  42. //Bottom
  43. Paint.setcolor (Color.green);
  44. Canvas.drawline (x, Y+fmi.bottom, 1024x768, y+fmi.bottom, paint);
  45. }

Get results:

Red Line is baseline, the top gray line is fontmetrics.top, the bottom of the Green Line is fontmetrics.bottom. (The green bottom and the blue descent are very close)

The character itself is centered between the Gray line and the Green Line , knowing that this is a good idea. Online said the use of Paint.gettextbounds methods are not reliable, you can see a "test" word and 6 words to get the bounds is different, the diagram of the rectangle can be very good to indicate that the function is the boundary of the character, not the font boundaries.

The Fontmetrics.top value is a negative number whose absolute value is the distance the font draws the boundary to baseline. So if the text is drawn in a rectangle with a fontmetrics height, the DrawText should pass in the-fontmetrics.top. To draw in the center position of the Targetrect, the baseline calculation formula is: Targetrect.centery ()-(fontmetrics.bottom-fontmetrics.top)/2-fontmetrics.top After optimization, it is:

(Targetrect.bottom + targetrect.top-fontmetrics.bottom-fontmetrics.top)/2

Solution:

So the initial code should be changed (by adding the horizontal center):

[Java]View Plaincopy print?
  1. @Override
  2. Public void OnDraw (canvas canvas) {
  3. Rect targetrect = new rect ( 200);
  4. Paint paint = new paint (Paint.anti_alias_flag);
  5. Paint.setstrokewidth (3);
  6. Paint.settextsize (80);
  7. String teststring = "test: ijkjqka:1234";
  8. Paint.setcolor (Color.cyan);
  9. Canvas.drawrect (targetrect, paint);
  10. Paint.setcolor (color.red);
  11. Fontmetricsint FontMetrics = Paint.getfontmetricsint ();
  12. //Reprint Please specify Source: http://blog.csdn.net/hursing
  13. int baseline = (Targetrect.bottom + targetrect.top-fontmetrics.bottom-fontmetrics.top)/ 2;
  14. //below this line is to achieve the horizontal center, drawtext corresponding to the incoming Targetrect.centerx ()
  15. Paint.settextalign (Paint.Align.CENTER);
  16. Canvas.drawtext (TestString, Targetrect.centerx (), baseline, paint);
  17. }

Effect (click to view larger image):

can also go to see the Android SDK source code,

$android 4.2/frameworks/base/corej/ava/android/text/boringlayout.java is an algorithm of TextView drawing text

Reprint Please specify source: http://blog.csdn.net/hursing

Android Canvas DrawText for vertical centering in Chinese

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.