1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph.utils;
14 import java.awt.FontMetrics;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
19 public final class TextUtil {
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;
33 int length = text.length();
35 int cumulatedLineWidth = 0;
37 int dotWidth = metrics.charWidth('.');
38 int dot3Width = 3*dotWidth;
39 boolean nonWhitespaceFound = false;
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;
52 nonWhitespaceFound = true;
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) + "'");
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;
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));
74 // Cannot word wrap a single character anything into the specified max width.
75 if (rollbackPos == 0) {
80 result.add(text.substring(0, rollbackPos) + "...");
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;
87 text = text.substring(nextLineStartPos);
88 length = text.length();
90 cumulatedLineWidth = 0;
91 nonWhitespaceFound = false;
96 cumulatedLineWidth += cWidth;
100 if (text.length() > 0)
103 return result.toArray(new String[result.size()]);