--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.scenegraph.utils;\r
+\r
+import java.awt.FontMetrics;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+\r
+public final class TextUtil {\r
+\r
+ /**\r
+ * @param text\r
+ * @param g\r
+ * @param bounds\r
+ * @return\r
+ */\r
+ public static String[] wordWrap(String text, FontMetrics metrics, int maxLineWidth) {\r
+ Collection<String> result = new ArrayList<String>();\r
+ int[] whitespacePos = new int[8];\r
+ int whitespaceTop = 0;\r
+\r
+ int pos = 0;\r
+ int length = text.length();\r
+\r
+ int cumulatedLineWidth = 0;\r
+\r
+ int dotWidth = metrics.charWidth('.');\r
+ int dot3Width = 3*dotWidth;\r
+ boolean nonWhitespaceFound = false;\r
+\r
+ out:\r
+ while (pos < length) {\r
+ char c = text.charAt(pos);\r
+ int cWidth = metrics.charWidth(c);\r
+ if (Character.isWhitespace(c)) {\r
+ if (nonWhitespaceFound) {\r
+ if (whitespacePos.length <= whitespaceTop)\r
+ whitespacePos = Arrays.copyOf(whitespacePos, whitespacePos.length*2);\r
+ whitespacePos[whitespaceTop++] = pos;\r
+ }\r
+ } else {\r
+ nonWhitespaceFound = true;\r
+ }\r
+\r
+// System.out.println("cumulated: " + cumulatedLineWidth);\r
+// System.out.println(" width: " + cWidth);\r
+// System.out.println(" max: " + maxLineWidth);\r
+ if (cumulatedLineWidth + cWidth > maxLineWidth) {\r
+// System.out.println("overran line: " + (result.size() + 1) + ": '" + text.substring(0, pos) + "'");\r
+\r
+ // Look for last whitespace position to cut at\r
+ int nextLineStartPos = -1;\r
+ if (whitespaceTop > 0) {\r
+ int cutPos = whitespacePos[--whitespaceTop];\r
+ result.add(text.substring(0, cutPos));\r
+ nextLineStartPos = cutPos + 1;\r
+ } else {\r
+ // No whitespace available, just cut the string and insert "..." at the end.\r
+ int rollbackWidth = cumulatedLineWidth + dot3Width;\r
+ int rollbackPos = pos;\r
+ while (rollbackPos > 0 && rollbackWidth > maxLineWidth) {\r
+ rollbackWidth -= metrics.charWidth(text.charAt(--rollbackPos));\r
+ }\r
+ // Cannot word wrap a single character anything into the specified max width.\r
+ if (rollbackPos == 0) {\r
+ result.add(text);\r
+ break out;\r
+ }\r
+\r
+ result.add(text.substring(0, rollbackPos) + "...");\r
+\r
+ // Search for next whitespace in the text after pos and start the next line from there.\r
+ int nextWhitespacePos = pos;\r
+ for (;nextWhitespacePos < length && !Character.isWhitespace(text.charAt(nextWhitespacePos)); ++nextWhitespacePos);\r
+ nextLineStartPos = nextWhitespacePos < length ? nextWhitespacePos + 1 : nextWhitespacePos;\r
+ }\r
+ text = text.substring(nextLineStartPos);\r
+ length = text.length();\r
+ pos = 0;\r
+ cumulatedLineWidth = 0;\r
+ nonWhitespaceFound = false;\r
+ whitespaceTop = 0;\r
+ continue;\r
+ }\r
+\r
+ cumulatedLineWidth += cWidth;\r
+ ++pos;\r
+ }\r
+\r
+ if (text.length() > 0)\r
+ result.add(text);\r
+\r
+ return result.toArray(new String[result.size()]);\r
+ }\r
+\r
+}\r