Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dry-Run of _calculateFontSize? #43

Open
om-ha opened this issue Jan 2, 2020 · 5 comments
Open

Dry-Run of _calculateFontSize? #43

om-ha opened this issue Jan 2, 2020 · 5 comments
Assignees
Labels
question Further information is requested

Comments

@om-ha
Copy link

om-ha commented Jan 2, 2020

Question

Is it possible to do a dry-run of _calculateFontSize without having to use AutoSizeText widget?

My use case requires calculating maximum number of lines and use the output value as a parameter for AutoSizeText widget.

What I'm trying to do is pass width and height with a maximum int for maxLines, in addition to the usual style and size parameters of AutoSizeText. In return I'd get fontSize from _calculateFontSize. All of this would be done without having to actually use AutoSizeText widget.

Version

  • Flutter version: 1.12.13+hotfix.5 (latest stable)
  • auto_size_text version: 2.1.0 (latest version)
@om-ha om-ha added the question Further information is requested label Jan 2, 2020
@simc
Copy link
Owner

simc commented Jan 16, 2020

Could you give me an example of what you are trying to achieve?

@om-ha
Copy link
Author

om-ha commented Jan 17, 2020

Hey @leisim

I want to be able to call this:

var result = _calculateFontSize(size, style, maxLines);
var fontSize = result[0] as double;
var textFits = result[1] as bool;

Without build context/without Auto Size Text widget. As a public helper method.

@om-ha
Copy link
Author

om-ha commented Jan 17, 2020

Why I need this? because I'm using low-level text API from flutter TextSpan and TextPainter to get "visible number of lines" in a complicated UI component. Then feeding visible number of lines to AutoSizeText.

To calculate "visible number of lines" correctly I need to figure out the font size first.

Now that I wrote all of this. I'll just try copying the content of "_calculateFontSize" and give it a try..

@simc
Copy link
Owner

simc commented Jan 17, 2020

Yes I understand that you want to get the number of lines but it would help if you could explain your goal. What do you want to do with the number of lines? Maybe AutoSizeText can already do what you want do build.

@om-ha
Copy link
Author

om-ha commented Jan 17, 2020

The feature I implemented successfully (with constant numbeOfLines 😐) is overlaying user-generated text in-front of a user-selected background image, think image editing software. The text is of variable length and needs to be resized properly but truncate any residues surpassing maximum font size. Here's how I implemented this:

I have a container widget of known width and height boxConstraints.

I have 3 labels: A (title), B (meta info), and C (subtitle), aligned vertically one after the other within the container widget.

  • Label B (meta info) has fixed font size and only one line. No resize needed. Text widget is used.
  • Label A (title) has variable font size within a range. [20, 50]
  • Label C (subtitle) has variable font size within a range. [12, 20]

The text of labels A and C could be really long so if we ever surpass maximum font-size, then truncation occurs.

So the solution for labels A and C's problem is:

  1. Considering infinite number of lines, calculate font-size within the respective [minFontSize, maxFontSize] range. According to the length of the text if it's too long/short, the calculated font-size might exceed the font size range. If this happens then just pick the lower/upper bound.
    1.1 _calculateFontSize could be used.
    1.2 Parameters: text, boxConstraints, minFontSize, maxFontSize, infinite numberOfLines
    1.3 returns: normalizedFontSize

  2. Use this calculated range-normalized font size to calculate visible number of lines.
    2.1 My method is used (bottom of this comment)
    2.2 Parameters: text, boxConstraints, fontSize
    2.3 returns: visibleNumberOfLines

  3. Use normalizedFontSize from Step1 with visibleNumberOfLines from Step2 to render the text and truncate it if necessary.

This opened issue is about Step1 in the the solution above.

Here's the reference code I wrote for Step2:

import 'dart:ui' as dartUI;

import 'package:flutter/material.dart';

/// Returns visible number of lines -- calcuates Line Height using TextPainter
int getVisibleNumberOfLines({
  String text,
  TextStyle textStyle,
  TextDirection textDirection,
  double availableWidth,
  double availableHeight,
  double minFontSize,
}) {
  // TODO complete calculating max lines correctly using `AutoSizeText`'s private method `_calculateFontSize`
  double fontSize = minFontSize ?? textStyle.fontSize;
  double largestLineHeight;

  // create new `TextStyle` for `TextPainter`
  final TextStyle textPainterStyle = textStyle.copyWith(
    fontSize: fontSize,
    height: null,
  );

  // text span
  final textSpan = TextSpan(
    text: text,
    style: textPainterStyle,
  );

  // text painter
  final textPainter = TextPainter(
    text: textSpan,
    textDirection: textDirection,
  );

  // layout text painter to allow computing line metrics
  textPainter.layout(
    minWidth: 0,
    maxWidth: availableWidth ?? availableHeight,
  );

  // compute line metrics
  List<dartUI.LineMetrics> lines = textPainter.computeLineMetrics();
  // sort lines descendingly using height property
  lines.sort((line1, line2) => line2.height.compareTo(line1.height));
  // store largest height
  largestLineHeight = lines.first.height;

  // calculate number of lines
  int visibleLinesNumber = (availableHeight / largestLineHeight).floor();
  return visibleLinesNumber;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants