포스트

Flutter Simple 그림판 (5) - 텍스트 컨테이너 줄바꿈 감지, 맞추기(word-character-breaking)(3)

character-breaking의 계산 부하를 줄이기 위해서, 각 문자마다 검사하지 않고, 일단 word 별로 검사하다가, 줄바꿈이 일어나면 해당 word를 character로 쪼개서 다시 character별 줄 바꿈 검사를 하기로 했음.

[영상]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
int calculateLinesCount(TextStyle style, double containerHeight) {
    // Using a space character to measure the height might be more reliable as it should
    // give us the height of an empty line of text, including leading.
    final TextPainter textPainter = TextPainter(
      text: TextSpan(text: ' ', style: style),
      maxLines: 1,
      textDirection: TextDirection.ltr,
    )..layout(minWidth: 0, maxWidth: double.infinity);

    // The height property acts as a multiplier to the font size.
    double styleHeight = style.fontSize! * (style.height ?? 1.0);
    // Measure the height of a space character as a proxy for line height.
    double measuredHeight = textPainter.size.height;
    print("measuredHeight: $measuredHeight");

    // Regard the line height as the maximum of the measured height and the style height.
    double lineHeight = measuredHeight > styleHeight ? measuredHeight : styleHeight;
    print("lineHeight: $lineHeight");

    // Calculate the number of lines that can fit in the container.
    int linesCount = containerHeight ~/ lineHeight;
    return linesCount;
  }

  String breakCharacterWithMeasurement(
      String input, TextStyle textStyle, double containerWidth, double containerHeight, TextAlign textAlign) {
    List lines = [];
    TextPainter textPainter = TextPainter(
      textDirection: TextDirection.ltr,
      textAlign: textAlign,
    );
    List words = input.split(' '); // Split the input into words.
    String currentLine = '';
    print("containerWidth: $containerWidth");
    print("containerHeight: $containerHeight");
    //
    double textWidth;
    double textWidthPadding = textStyle.fontSize! * 0.5;
    // modify the containerHeight to be the multiple of the text height
    int linesCount = calculateLinesCount(textStyle, containerHeight);
    print("linesCount: $linesCount");
    int currentLineCount = 0;

    for (String word in words) {
      // Handle each word
      bool isFirstCharacterOfWord = true;
      for (int i = 0; i  containerWidth) {
          if (!isFirstCharacterOfWord || currentLine.isNotEmpty) {
            // If the line is not empty, or if it's not the first character of the word, add the current line to the lines list
            lines.add(currentLine);
            currentLineCount++;
            if (currentLineCount >= linesCount) break; // Stop if the maximum number of lines is reached
            currentLine = character; // Start a new line with the current character
          } else {
            // If it's the first character of the word and the line is empty
            currentLine = character; // Add the character to the current line
          }
          isFirstCharacterOfWord = false;
        } else {
          // If the character fits, add it to the current line
          currentLine = testLine;
          isFirstCharacterOfWord = false;
        }
      }
      // After processing a word, add a space if it's not the end of a line
      if (currentLineCount = linesCount) break;
    }

    // Add any remaining text in the currentLine to lines, if there's space
    if (!currentLine.isEmpty && currentLineCount < linesCount) {
      lines.add(currentLine.trim());
    }

    return lines.join(&#x27;\n&#x27;).trim();
  }

sticker

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.