textflutterbaselinefontmetrics

What is the difference between alphabetic and ideographic in Flutter's TextBaseline enum


The TextBaseline enum in Flutter has two options:

How do these values actually change the baseline?


Solution

  • TextBaseline.alphabetic

    The alphabetic baseline is the line that the letters in alphabets like English sit on. Here is an example:

    enter image description here

    You can see that the English letters sit nicely on the line, but it cuts through the Chinese characters.

    TextBaseline.ideographic

    When you use the ideographic option, though, the baseline is at the bottom of the text area. Note that the Chinese characters don't actually sit right on the line. Rather, the line is at the very bottom of the text line.

    enter image description here

    Supplemental code

    You can plug this into a CustomPaint widget (as described here) to reproduce the above examples.

    @override
    void paint(Canvas canvas, Size size) {
      final textStyle = TextStyle(
        color: Colors.black,
        fontSize: 30,
      );
      final textSpan = TextSpan(
        text: 'My text 文字',
        style: textStyle,
      );
      final textPainter = TextPainter(
        text: textSpan,
        textDirection: TextDirection.ltr,
      );
      textPainter.layout(
        minWidth: 0,
        maxWidth: size.width,
      );
    
      print('width: ${textPainter.width}');
      print('height: ${textPainter.height}');
    
      // draw a rectangle around the text
      final left = 0.0;
      final top = 0.0;
      final right = textPainter.width;
      final bottom = textPainter.height;
      final rect = Rect.fromLTRB(left, top, right, bottom);
      final paint = Paint()
        ..color = Colors.red
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1;
      canvas.drawRect(rect, paint);
    
      // draw the baseline
      final distanceToBaseline =
          textPainter.computeDistanceToActualBaseline(TextBaseline.ideographic);
      print('distanceToBaseline: ${distanceToBaseline}');
      canvas.drawLine(
        Offset(0, distanceToBaseline),
        Offset(textPainter.width, distanceToBaseline),
        paint,
      );
    
      // draw the text
      final offset = Offset(0, 0);
      textPainter.paint(canvas, offset);
    }