113

This seems like a basic question, but I couldn't find a similar one on SO. While reading the documentation, I was having trouble grasping the concepts. I want to understand what the difference is between top and ascent and also bottom and descent. And where exactly is the baseline? Do you have a diagram to help me visualize it?

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393

2 Answers2

365

Let's first review what the documentation says:

  • Top - The maximum distance above the baseline for the tallest glyph in the font at a given text size.
  • Ascent - The recommended distance above the baseline for singled spaced text.
  • Descent - The recommended distance below the baseline for singled spaced text.
  • Bottom - The maximum distance below the baseline for the lowest glyph in the font at a given text size.
  • Leading - The recommended additional space to add between lines of text.

Note that the Baseline is what the first four are measured from. It is line which forms the base that the text sits on, even though some characters (like g, y, j, etc.) might have parts that go below the line. It is comparable to the lines you write on in a lined notebook.

Here is a picture to help visualize these things:

FontMetrics showing top, ascent, baseline, decent, bottom, and leading

Remember that when drawing on a canvas in Java and Android, going down is an increase in y and going up is a decrease in y. That means that FontMetrics' top and ascent are negative numbers since they are measured from the baseline (while descent and bottom are positive numbers). Thus, to get the distance from top to bottom you would need to do (bottom - top).

The leading is the distance between the bottom of one line and the top of the next line. In the picture above, it is the space between the orange of Line 1 and the purple of Line 2. As @MajorTom noted below, in typography the term is more properly defined as "the distance between the baselines of successive lines of type."* However, Android seems to use the term in the more historical sense. The word (pronounced "ledding") comes from the lead strip that the old typesetters used to put between lines of type. It was basically just a way to adjust the line spacing. In Android I've never actually seen the leading be anything other than 0 and I haven't seen it used for anything in the source code. (Correct me if you know where it is used to calculate anything.) You can change the line spacing in a TextView with setLineSpacing in code or android:lineSpacingExtra and android:lineSpacingMultiplier in xml. These methods, however, do not make use of or modify the leading.

Check out these links for more information:

Explore more

In order to explore Font Metrics more, I made a simple project.

enter image description here

Rather than listing all the code here. I added the project to GitHub. You can either clone the project, or copy the following files into a new project.

Do letters ever go above top or below bottom?

Not usually, but they could. Top and bottom, as I understand them, are set by the font (hence "FontMetrics"), so a font maker could make a glyph go higher than whatever they say the top is (or lower than the bottom). Also, with combining diacritical marks in Unicode it can very easily happen. Here is a rather extreme example (taken from here): M̵̳̙͔̟̱͕̓̀̄̉̅ͧ̋͊͌͑́͌ͪ̒̿̀̚a͔̟̝͔ͥ̈́̏ͮͯ̇͆̊̒ͦͦ͘͢͜y̵̴̢͕̝̩̱͈͕̼̣͕̟̌͗̾ͤ̎͌̄ͣͨ͊ͬb̡̯̰̪̜͙̟̝̠͚̜̥̙̤̃ͨ̋̒̒̊ͧͤ͐̓͋̌̾̇̔̈́̀́͡͠e̵ͯͪ̿̿̂̄ͫ̃҉͏͎̣̹̱̜͉̦̞̪̘̠̝̝͍̼̜̖̥̭͟ ̣̞͙͚̝̰̞̹̗̲̣͙͍͍̀̓͊̂̋ͣ̏̑̍̊͌ͩ͐̎̀ͣͣ̚͟ͅh̛͋̏̍̆ͤ͛͐ͨ̌̋ͤ̎̂ͨ̂̓̑̚̕͟͏̻̣͖̖͚͚͓̲̼̪ȁ̔̅̿͐̑͡͏̝͓̮͚̘̦̰͚͎͔͉͚̮̠̕͜ͅṱ̱̼̖̓̂ͭ̏̅͂ͥ͌ͯ͌͠sͪ̓ͪ̄̌̓ͧ͋͐ͬ̅̑҉̨̪̬͎͍̥̬?̡̮̳͙͓͔̹̘̹͓̘̻̦̣͎̫̐ͤ̐͛́͝ ̧̦̼̘͕̪̠̙͖̦̯̦̘͉͈͕͔̘̻̲͑ͨ̊̈́̐ͫ͐̌ͯ̀͘͝Ḩ̷̸̸̹͉̩̜̹̞ͯ̃̃ͧͬͨ̌̀̾̐̈̇ͧ͛̃͐̀ͦ͞A̴̦̗̬̠͙̭͉̟̺͇̭̰͔͕̯̅̃͋ͪ̈́̉̓̌ͯ̈́͆̋̀ͤ̇̂̿̈́̂͡͡Ṱ̲͎͉̣̳̺̱̜̦̬͕̣͉͇͊̌ͥ͐͒̈́̓́ͥ́́̋͂̅ͬ̆͗ͥ̕͢͡S̍ͧ͗̒͗̂̈ͬ͊̚̚͢͏̗̣̳ͅ!̶̨̡͇͚̙͚̭̱̣̲̳̤̞̫̗̣̦̮̖̞͒͆̿̄͑̃̎͡

Plugging that string into Android we get this:

enter image description here

The diacritical marks go above the top and below the bottom. It is interesting to note that the total width and height are correctly measured by the text bounds, though.

Anyway, for all practical purposes in your programming, you can just assume that the max and min for glyph letters are top and bottom. And usually they will stay within ascent and descent. If for whatever reason you need to know for sure if the letters go beyond top or bottom you can use TextPaint.getTextBounds.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • Nice! Do you know in what units are the ascent, descent etc measured in? Are they in pixels? They are float values but not sure how they correspond to the screen. Got them checked in photoshop to see if it is pixels and there is a slight difference of a few units; pixels being smaller. – Vikram Gupta Apr 06 '16 at 23:30
  • @VikramGupta. The units are pixels. I'm not sure what caused the difference with your photoshop image check. – Suragch Feb 03 '17 at 09:48
  • Thanks for the useful explanation and the app. But, can u further explain, what is exactly `Top`? Will there be any letter tall enough to touch the `Top` line? For instance, "M", "l" seems to be the tallest letter. None of them touching `Top`. – Cheok Yan Cheng Aug 26 '17 at 17:06
  • @CheokYanCheng, see the update at the end of my answer. – Suragch Aug 27 '17 at 07:48
  • @Suragch Thanks for the info. I use your app to understand more. I expect "Ascent" line will just touch the top of the font nicely as in your screenshot. However, from the latest http://i.imgur.com/aRxgjvu.png , it is not touching the tallest character "M". Do you have any idea why? – Cheok Yan Cheng Aug 27 '17 at 18:02
  • @CheokYanCheng, That is what I expected at first, too. But remember that "M" is not necessarily the tallest glyph in a font. Or even if it is the tallest letter in a particular font, the font makers may be leaving room for other characters which could be taller. Don't forget emoji. I just tested the emoji and it touched both the ascent and decent lines. So usually Latin letters never actually touch the ascent line, which makes the picture in my answer a little deceptive. – Suragch Aug 28 '17 at 04:46
5

Leading is NOT space between lines in typography. Apparently this is something Android code does not take into account. We've been struggling with this ourselves. The proper definition of leading (from Wikipedia):

In typography, leading /ˈlɛdɪŋ/ refers to the distance between the baselines of successive lines of type. The term originated in the days of hand-typesetting, when thin strips of lead were inserted into the forms to increase the vertical distance between lines of type.

From what I can tell, Android does not have a way to specify this.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
MajorTom
  • 1,285
  • 2
  • 9
  • 9
  • +1 for helping me understand leading better. As far changing the leading goes, you can use TextView's `setLineSpacing` in code or `android:lineSpacingExtra` and `android:lineSpacingMultiplier` in xml. – Suragch Jun 11 '16 at 00:12
  • Thanks - yes we were told to use `android:lineSpacingExtra` which would put a measurement between the actual space *between* the lines. It's not leading, but it seems like the only way to manage the spacing. It's a problem because there's no such measurement in typography, and there's no such way to specify that measure in Sketch or Zepelin (the tools we use). Plus it doesn't match the leading. – MajorTom Jun 12 '16 at 12:01
  • 1
    If typographical leading is the distance between baselines, it seems like it should be easy to calculate. – Suragch Jun 12 '16 at 12:38
  • That's what I thought. Is there a way to do it programmatically? I was hoping with the methods Android provides that there might be a way to do it. The devs we work with don't seem to know. – MajorTom Jun 12 '16 at 12:53
  • It has been a while since I have worked with this, but if I were going to take it up again I would start [here](http://stackoverflow.com/questions/3654321/measuring-text-height-to-be-drawn-on-canvas-android) and [here](http://stackoverflow.com/questions/5043427/how-to-get-ascender-descender-and-x-height-for-a-given-font) and experiment with different text and fonts. Even if it isn't straight forward, I can't believe that there isn't a way to calculate what you need. – Suragch Jun 12 '16 at 14:51
  • See [this question](http://stackoverflow.com/questions/14276853/how-to-measure-textview-height-based-on-device-width-and-font-size) as well. – Suragch Jun 12 '16 at 14:55
  • That is indeed the definition from typography, but in CSS at least line-gaps (due to leading) are divided into the top *and* bottom parts of a line, and thus line height is measured from between line boxes. This is a better way that classical typography, which was not possible to do in the days of yore. – Marius Apr 07 '17 at 15:38