]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/TextUtil.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / TextUtil.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.utils;
13
14 import java.awt.FontMetrics;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
18
19 public final class TextUtil {
20
21     /**
22      * @param text
23      * @param g
24      * @param bounds
25      * @return
26      */
27     public static String[] wordWrap(String text, FontMetrics metrics, int maxLineWidth) {
28         Collection<String> result = new ArrayList<String>();
29         int[] whitespacePos = new int[8];
30         int whitespaceTop = 0;
31
32         int pos = 0;
33         int length = text.length();
34
35         int cumulatedLineWidth = 0;
36
37         int dotWidth = metrics.charWidth('.');
38         int dot3Width = 3*dotWidth;
39         boolean nonWhitespaceFound = false;
40
41         out:
42             while (pos < length) {
43                 char c = text.charAt(pos);
44                 int cWidth = metrics.charWidth(c);
45                 if (Character.isWhitespace(c)) {
46                     if (nonWhitespaceFound) {
47                         if (whitespacePos.length <= whitespaceTop)
48                             whitespacePos = Arrays.copyOf(whitespacePos, whitespacePos.length*2);
49                         whitespacePos[whitespaceTop++] = pos;
50                     }
51                 } else {
52                     nonWhitespaceFound = true;
53                 }
54
55 //            System.out.println("cumulated: " + cumulatedLineWidth);
56 //            System.out.println("    width: " + cWidth);
57 //            System.out.println("    max:   " + maxLineWidth);
58                 if (cumulatedLineWidth + cWidth > maxLineWidth) {
59 //                System.out.println("overran line: " + (result.size() + 1) + ": '" + text.substring(0, pos) + "'");
60
61                     // Look for last whitespace position to cut at
62                     int nextLineStartPos = -1;
63                     if (whitespaceTop > 0) {
64                         int cutPos = whitespacePos[--whitespaceTop];
65                         result.add(text.substring(0, cutPos));
66                         nextLineStartPos = cutPos + 1;
67                     } else {
68                         // No whitespace available, just cut the string and insert "..." at the end.
69                         int rollbackWidth = cumulatedLineWidth + dot3Width;
70                         int rollbackPos = pos;
71                         while (rollbackPos > 0 && rollbackWidth > maxLineWidth) {
72                             rollbackWidth -= metrics.charWidth(text.charAt(--rollbackPos));
73                         }
74                         // Cannot word wrap a single character anything into the specified max width.
75                         if (rollbackPos == 0) {
76                             result.add(text);
77                             break out;
78                         }
79
80                         result.add(text.substring(0, rollbackPos) + "...");
81
82                         // Search for next whitespace in the text after pos and start the next line from there.
83                         int nextWhitespacePos = pos;
84                         for (;nextWhitespacePos < length && !Character.isWhitespace(text.charAt(nextWhitespacePos)); ++nextWhitespacePos);
85                         nextLineStartPos = nextWhitespacePos < length ? nextWhitespacePos + 1 : nextWhitespacePos;
86                     }
87                     text = text.substring(nextLineStartPos);
88                     length = text.length();
89                     pos = 0;
90                     cumulatedLineWidth = 0;
91                     nonWhitespaceFound = false;
92                     whitespaceTop = 0;
93                     continue;
94                 }
95
96                 cumulatedLineWidth += cWidth;
97                 ++pos;
98             }
99
100         if (text.length() > 0)
101             result.add(text);
102
103         return result.toArray(new String[result.size()]);
104     }
105
106 }