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