Skip to main content
summaryrefslogblamecommitdiffstats
blob: 24ed2558840d8335640b767defdb87fad059cfa9 (plain) (tree)





























































































































                                                                                           
/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout;

import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;

public class MultiLineLabel extends Label {
	private static String ELLIPSIS = "..."; //$NON-NLS-1$

	protected void paintFigure(Graphics graphics) {
		if (isOpaque()) {
			graphics.fillRectangle(getBounds());
		}
		Rectangle bounds = getBounds();
		graphics.translate(bounds.x, bounds.y);
		drawText(graphics);
		graphics.translate(-bounds.x, -bounds.y);
	}

	private void drawText(Graphics graphics) {
		String[] strings = splitString(getText());
		int y = 0;
		int lineHeight = FigureUtilities.getFontMetrics(getFont()).getHeight();
		for (int i = 0; i < strings.length; i++) {
			graphics.drawText(getSubStringText(strings[i]), 0, y);
			y += lineHeight;
		}

	}

	private String[] splitString(String text) {
		String[] lines = new String[1];
		int start = 0, pos;
		do {
			pos = text.indexOf('\n', start);
			if (pos == -1) {
				lines[lines.length - 1] = text.substring(start);
			} else {
				boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r');
				lines[lines.length - 1] = text.substring(start, pos
						- (crlf ? 1 : 0));
				start = pos + 1;
				String[] newLines = new String[lines.length + 1];
				System.arraycopy(lines, 0, newLines, 0, lines.length);
				lines = newLines;
			}
		} while (pos != -1);
		return lines;
	}

	public String getSubStringText(String text) {
		String subStringText = text;

		Font currentFont = getFont();
		int textWidth = FigureUtilities.getTextWidth(text, currentFont);
		if (textWidth - getSize().width <= 0) {
			return subStringText;
		}

		Dimension effectiveSize = new Dimension(getSize().width, 0);

		int dotsWidth = FigureUtilities.getTextWidth(ELLIPSIS, currentFont);

		if (effectiveSize.width < dotsWidth) {
			effectiveSize.width = dotsWidth;
		}

		int subStringLength = getLargestSubstringConfinedTo(text, currentFont,
				effectiveSize.width - dotsWidth);
		subStringText = new String(text.substring(0, subStringLength)
				+ ELLIPSIS);
		return subStringText;
	}

	int getLargestSubstringConfinedTo(String s, Font f, int availableWidth) {
		FontMetrics metrics = FigureUtilities.getFontMetrics(f);
		int min, max;
		float avg = metrics.getAverageCharWidth();
		min = 0;
		max = s.length() + 1;

		// The size of the current guess
		int guess = 0, guessSize = 0;
		while ((max - min) > 1) {
			// Pick a new guess size
			// New guess is the last guess plus the missing width in pixels
			// divided by the average character size in pixels
			guess = guess + (int) ((availableWidth - guessSize) / avg);

			if (guess >= max) {
				guess = max - 1;
			}
			if (guess <= min) {
				guess = min + 1;
			}

			// Measure the current guess
			guessSize = FigureUtilities
					.getTextExtents(s.substring(0, guess), f).width;

			if (guessSize < availableWidth) {
				// We did not use the available width
				min = guess;
			} else {
				// We exceeded the available width
				max = guess;
			}
		}
		return min;
	}
}

Back to the top