/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Anton Leherbauer (Wind River Systems) - Bug 439419
 *     Angelo Zerr <angelo.zerr@gmail.com> - Customize different line spacing of StyledText - Bug 522020
 *******************************************************************************/
package org.eclipse.swt.custom;


import java.util.*;
import java.util.List;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * A StyledTextRenderer renders the content of a StyledText widget.
 * This class can be used to render to the display or to a printer.
 */
class StyledTextRenderer {
	Device device;
	StyledText styledText;
	StyledTextContent content;

	/* Custom line spacing */
	StyledTextLineSpacingProvider lineSpacingProvider;
	boolean lineSpacingComputing;

	/* Font info */
	Font regularFont, boldFont, italicFont, boldItalicFont;
	int tabWidth;
	int ascent, descent;
	int averageCharWidth;
	int tabLength;	//tab length in spaces

	/* Line data */
	int topIndex = -1;
	TextLayout[] layouts;
	int lineCount;
	LineSizeInfo[] lineSizes;
	LineInfo[] lines;
	int maxWidth;
	int maxWidthLineIndex;
	boolean idleRunning;

	/* Bullet */
	Bullet[] bullets;
	int[] bulletsIndices;
	int[] redrawLines;

	/* Style data */
	int[] ranges;
	int styleCount;
	StyleRange[] styles;
	StyleRange[] stylesSet;
	int stylesSetCount = 0;
	boolean hasLinks, fixedPitch;
	final static int BULLET_MARGIN = 8;

	final static boolean COMPACT_STYLES = true;
	final static boolean MERGE_STYLES = true;

	final static int GROW = 32;
	final static int IDLE_TIME = 50;
	final static int CACHE_SIZE = 300;

	final static int BACKGROUND = 1 << 0;
	final static int ALIGNMENT = 1 << 1;
	final static int INDENT = 1 << 2;
	final static int JUSTIFY = 1 << 3;
	final static int SEGMENTS = 1 << 5;
	final static int TABSTOPS = 1 << 6;
	final static int WRAP_INDENT = 1 << 7;
	final static int SEGMENT_CHARS = 1 << 8;
	final static int VERTICAL_INDENT = 1 << 9;

	static class LineSizeInfo {

		private static final int RESETED_SIZE = -1;

		/* Line size */
		int height;
		int width;

		public LineSizeInfo() {
			resetSize();
		}

		/**
		 * Reset the line size.
		 */
		void resetSize() {
			height = RESETED_SIZE;
			width = RESETED_SIZE;
		}

		/**
		 * Returns true if the TextLayout get from the layout pool can be directly used
		 * or must be refreshed with styles.
		 *
		 * @return true if the TextLayout get from the layout pool can be directly used
		 *         or must be refreshed with styles.
		 */
		boolean canLayout() {
			return !needsRecalculateWidth();
		}

		/**
		 * Returns true if it needs to recalculate the line size and false
		 * otherwise.
		 *
		 * @return true if it needs to recalculate the line size and false
		 *         otherwise.
		 */
		boolean needsRecalculateSize() {
			return needsRecalculateWidth() || needsRecalculateHeight();
		}

		/**
		 * Returns true if it needs to recalculate the line width and false
		 * otherwise.
		 *
		 * @return true if it needs to recalculate the line width and false
		 *         otherwise.
		 */
		boolean needsRecalculateWidth() {
			return width == RESETED_SIZE;
		}

		/**
		 * Returns true if it needs to recalculate the line height and false
		 * otherwise.
		 *
		 * @return true if it needs to recalculate the line height and false
		 *         otherwise.
		 */
		boolean needsRecalculateHeight() {
			return height == RESETED_SIZE;
		}
	}

	static class LineInfo {
		int flags;
		Color background;
		int alignment;
		int indent;
		int wrapIndent;
		boolean justify;
		int[] segments;
		char[] segmentsChars;
		int[] tabStops;
		int verticalIndent;

		public LineInfo() {
		}
		public LineInfo(LineInfo info) {
			if (info != null) {
				flags = info.flags;
				background = info.background;
				alignment = info.alignment;
				indent = info.indent;
				wrapIndent = info.wrapIndent;
				justify = info.justify;
				segments = info.segments;
				segmentsChars = info.segmentsChars;
				tabStops = info.tabStops;
				verticalIndent = info.verticalIndent;
			}
		}
	}
	static int cap (TextLayout layout, int offset) {
		if (layout == null) return offset;
		return Math.min (layout.getText().length() -1, Math.max (0, offset));
	}

StyledTextRenderer(Device device, StyledText styledText) {
	this.device = device;
	this.styledText = styledText;
}
int addMerge(int[] mergeRanges, StyleRange[] mergeStyles, int mergeCount, int modifyStart, int modifyEnd) {
	int rangeCount = styleCount << 1;
	StyleRange endStyle = null;
	int endStart = 0, endLength = 0;
	if (modifyEnd < rangeCount) {
		endStyle = styles[modifyEnd >> 1];
		endStart = ranges[modifyEnd];
		endLength = ranges[modifyEnd + 1];
	}
	int grow = mergeCount - (modifyEnd - modifyStart);
	if (rangeCount + grow >= ranges.length) {
		int[] tmpRanges = new int[ranges.length + grow + (GROW << 1)];
		System.arraycopy(ranges, 0, tmpRanges, 0, modifyStart);
		StyleRange[] tmpStyles = new StyleRange[styles.length + (grow >> 1) + GROW];
		System.arraycopy(styles, 0, tmpStyles, 0, modifyStart >> 1);
		if (rangeCount > modifyEnd) {
			System.arraycopy(ranges, modifyEnd, tmpRanges, modifyStart + mergeCount, rangeCount - modifyEnd);
			System.arraycopy(styles, modifyEnd >> 1, tmpStyles, (modifyStart + mergeCount) >> 1, styleCount - (modifyEnd >> 1));
		}
		ranges = tmpRanges;
		styles = tmpStyles;
	} else {
		if (rangeCount > modifyEnd) {
			System.arraycopy(ranges, modifyEnd, ranges, modifyStart + mergeCount, rangeCount - modifyEnd);
			System.arraycopy(styles, modifyEnd >> 1, styles, (modifyStart + mergeCount) >> 1, styleCount - (modifyEnd >> 1));
		}
	}
	if (MERGE_STYLES) {
		int j = modifyStart;
		for (int i = 0; i < mergeCount; i += 2) {
			if (j > 0 && ranges[j - 2] + ranges[j - 1] == mergeRanges[i] && mergeStyles[i >> 1].similarTo(styles[(j - 2) >> 1])) {
				ranges[j - 1] += mergeRanges[i + 1];
			} else {
				styles[j >> 1] = mergeStyles[i >> 1];
				ranges[j++] = mergeRanges[i];
				ranges[j++] = mergeRanges[i + 1];
			}
		}
		if (endStyle != null && ranges[j - 2] + ranges[j - 1] == endStart && endStyle.similarTo(styles[(j - 2) >> 1])) {
			ranges[j - 1] += endLength;
			modifyEnd += 2;
			mergeCount += 2;
		}
		if (rangeCount > modifyEnd) {
			System.arraycopy(ranges, modifyStart + mergeCount, ranges, j, rangeCount - modifyEnd);
			System.arraycopy(styles, (modifyStart + mergeCount) >> 1, styles, j >> 1, styleCount - (modifyEnd >> 1));
		}
		grow = (j - modifyStart) - (modifyEnd - modifyStart);
	} else {
		System.arraycopy(mergeRanges, 0, ranges, modifyStart, mergeCount);
		System.arraycopy(mergeStyles, 0, styles, modifyStart >> 1, mergeCount >> 1);
	}
	styleCount += grow >> 1;
	return grow;
}
int addMerge(StyleRange[] mergeStyles, int mergeCount, int modifyStart, int modifyEnd) {
	int grow = mergeCount - (modifyEnd - modifyStart);
	StyleRange endStyle = null;
	if (modifyEnd < styleCount) endStyle = styles[modifyEnd];
	if (styleCount + grow >= styles.length) {
		StyleRange[] tmpStyles = new StyleRange[styles.length + grow + GROW];
		System.arraycopy(styles, 0, tmpStyles, 0, modifyStart);
		if (styleCount > modifyEnd) {
			System.arraycopy(styles, modifyEnd, tmpStyles, modifyStart + mergeCount, styleCount - modifyEnd);
		}
		styles = tmpStyles;
	} else {
		if (styleCount > modifyEnd) {
			System.arraycopy(styles, modifyEnd, styles, modifyStart + mergeCount, styleCount - modifyEnd);
		}
	}
	if (MERGE_STYLES) {
		int j = modifyStart;
		for (int i = 0; i < mergeCount; i++) {
			StyleRange newStyle = mergeStyles[i], style;
			if (j > 0 && (style = styles[j - 1]).start + style.length == newStyle.start && newStyle.similarTo(style)) {
				style.length += newStyle.length;
			} else {
				styles[j++] = newStyle;
			}
		}
		StyleRange style = styles[j - 1];
		if (endStyle != null && style.start + style.length == endStyle.start && endStyle.similarTo(style)) {
			style.length += endStyle.length;
			modifyEnd++;
			mergeCount++;
		}
		if (styleCount > modifyEnd) {
			System.arraycopy(styles, modifyStart + mergeCount, styles, j, styleCount - modifyEnd);
		}
		grow = (j - modifyStart) - (modifyEnd - modifyStart);
	} else {
		System.arraycopy(mergeStyles, 0, styles, modifyStart, mergeCount);
	}
	styleCount += grow;
	return grow;
}
void calculate(int startLine, int lineCount) {
	int endLine = startLine + lineCount;
	if (startLine < 0 || endLine > lineSizes.length) {
		return;
	}
	int hTrim = styledText.leftMargin + styledText.rightMargin + styledText.getCaretWidth();
	for (int i = startLine; i < endLine; i++) {
		LineSizeInfo line = getLineSize(i);
		if (line.needsRecalculateSize()) {
			TextLayout layout = getTextLayout(i);
			Rectangle rect = layout.getBounds();
			line.width = rect.width + hTrim;
			line.height = rect.height;
			disposeTextLayout(layout);
		}
		if (line.width > maxWidth) {
			maxWidth = line.width;
			maxWidthLineIndex = i;
		}
	}
}
LineSizeInfo getLineSize(int i) {
	if (lineSizes[i] == null) {
		lineSizes[i] = new LineSizeInfo();
	}
	return lineSizes[i];
}
void calculateClientArea () {
	int index = Math.max (0, styledText.getTopIndex());
	int lineCount = content.getLineCount();
	int height = styledText.getClientArea().height;
	int y = 0;
	/*
	 * There exists a possibility of ArrayIndexOutOfBounds Exception in
	 * below code, exact scenario not known. To avoid this exception added
	 * check for 'index' value, refer Bug 471192.
	 */
	while (height > y && lineCount > index && lineSizes.length > index) {
		calculate(index, 1);
		y += lineSizes[index++].height;
	}
}
void calculateIdle () {
	if (idleRunning) return;
	Runnable runnable = new Runnable() {
		@Override
		public void run() {
			if (styledText == null) return;
			int i;
			long start = System.currentTimeMillis();
			for (i = 0; i < lineCount; i++) {
				LineSizeInfo line = getLineSize(i);
				if (line.needsRecalculateSize()) {
					calculate(i, 1);
					if (System.currentTimeMillis() - start > IDLE_TIME) break;
				}
			}
			if (i < lineCount) {
				Display display = styledText.getDisplay();
				display.asyncExec(this);
			} else {
				idleRunning = false;
				styledText.setScrollBars(true);
				ScrollBar bar = styledText.getVerticalBar();
				if (bar != null) {
					bar.setSelection(styledText.getVerticalScrollOffset());
				}
			}
		}
	};
	Display display = styledText.getDisplay();
	display.asyncExec(runnable);
	idleRunning = true;
}
void clearLineBackground(int startLine, int count) {
	if (lines == null) return;
	for (int i = startLine; i < startLine + count; i++) {
		LineInfo info = lines[i];
		if (info != null) {
			info.flags &= ~BACKGROUND;
			info.background = null;
			if (info.flags == 0) lines[i] = null;
		}
	}
}
void clearLineStyle(int startLine, int count) {
	if (lines == null) return;
	for (int i = startLine; i < startLine + count; i++) {
		LineInfo info = lines[i];
		if (info != null) {
			info.flags &= ~(ALIGNMENT | INDENT | VERTICAL_INDENT | WRAP_INDENT | JUSTIFY | TABSTOPS);
			if (info.flags == 0) lines[i] = null;
		}
	}
}
void copyInto(StyledTextRenderer renderer) {
	if (ranges != null) {
		int[] newRanges = renderer.ranges = new int[styleCount << 1];
		System.arraycopy(ranges, 0, newRanges, 0, newRanges.length);
	}
	if (styles != null) {
		StyleRange[] newStyles = renderer.styles = new StyleRange[styleCount];
		for (int i = 0; i < newStyles.length; i++) {
			newStyles[i] = (StyleRange)styles[i].clone();
		}
		renderer.styleCount = styleCount;
	}
	if (lines != null) {
		LineInfo[] newLines = renderer.lines = new LineInfo[lineCount];
		for (int i = 0; i < newLines.length; i++) {
			newLines[i] = new LineInfo(lines[i]);
		}
		renderer.lineCount = lineCount;
	}
}
void dispose() {
	if (boldFont != null) boldFont.dispose();
	if (italicFont != null) italicFont.dispose();
	if (boldItalicFont != null) boldItalicFont.dispose();
	boldFont = italicFont = boldItalicFont = null;
	reset();
	content = null;
	device = null;
	styledText = null;
}
void disposeTextLayout (TextLayout layout) {
	if (layouts != null) {
		for (TextLayout l : layouts) {
			if (l == layout) return;
		}
	}
	layout.dispose();
}
void drawBullet(Bullet bullet, GC gc, int paintX, int paintY, int index, int lineAscent, int lineDescent) {
	StyleRange style = bullet.style;
	GlyphMetrics metrics = style.metrics;
	Color color = style.foreground;
	if (color != null) gc.setForeground(color);
	Font font = style.font;
	if (font != null) gc.setFont(font);
	String string = "";
	int type = bullet.type & (ST.BULLET_DOT|ST.BULLET_NUMBER|ST.BULLET_LETTER_LOWER|ST.BULLET_LETTER_UPPER);
	switch (type) {
		case ST.BULLET_DOT: string = "\u2022"; break;
		case ST.BULLET_NUMBER: string = String.valueOf(index + 1); break;
		case ST.BULLET_LETTER_LOWER: string = String.valueOf((char) (index % 26 + 97)); break;
		case ST.BULLET_LETTER_UPPER: string = String.valueOf((char) (index % 26 + 65)); break;
	}
	if ((bullet.type & ST.BULLET_TEXT) != 0) string += bullet.text;
	Display display = styledText.getDisplay();
	TextLayout layout = new TextLayout(display);
	layout.setText(string);
	layout.setAscent(lineAscent);
	layout.setDescent(lineDescent);
	style = (StyleRange)style.clone();
	style.metrics = null;
	if (style.font == null) style.font = getFont(style.fontStyle);
	layout.setStyle(style, 0, string.length());
	int x = paintX + Math.max(0, metrics.width - layout.getBounds().width - BULLET_MARGIN);
	layout.draw(gc, x, paintY);
	layout.dispose();
}
int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackground, Color widgetForeground) {
	TextLayout layout = getTextLayout(lineIndex);
	String line = content.getLine(lineIndex);
	int lineOffset = content.getOffsetAtLine(lineIndex);
	int lineLength = line.length();
	Point selection = styledText.getSelection();
	int selectionStart = selection.x - lineOffset;
	int selectionEnd = selection.y - lineOffset;
	if (styledText.getBlockSelection()) {
		selectionStart = selectionEnd = 0;
	}
	Rectangle client = styledText.getClientArea();
	Color lineBackground = getLineBackground(lineIndex, null);
	StyledTextEvent event = styledText.getLineBackgroundData(lineOffset, line);
	if (event != null && event.lineBackground != null) lineBackground = event.lineBackground;
	int height = layout.getBounds().height;
	int verticalIndent = layout.getVerticalIndent();
	if (lineBackground != null) {
		if (verticalIndent > 0) {
			gc.setBackground(widgetBackground);
			gc.fillRectangle(client.x, paintY, client.width, verticalIndent);
		}
		gc.setBackground(lineBackground);
		gc.fillRectangle(client.x, paintY + verticalIndent, client.width, height - verticalIndent);
	} else {
		gc.setBackground(widgetBackground);
		styledText.drawBackground(gc, client.x, paintY, client.width, height);
	}
	gc.setForeground(widgetForeground);
	if (selectionStart == selectionEnd || (selectionEnd <= 0 && selectionStart > lineLength - 1)) {
		layout.draw(gc, paintX, paintY);
	} else {
		int start = Math.max(0, selectionStart);
		int end = Math.min(lineLength, selectionEnd);
		Color selectionFg = styledText.getSelectionForeground();
		Color selectionBg = styledText.getSelectionBackground();
		int flags;
		if ((styledText.getStyle() & SWT.FULL_SELECTION) != 0) {
			flags = SWT.FULL_SELECTION;
		} else {
			flags = SWT.DELIMITER_SELECTION;
		}
		if (selectionStart <= lineLength && lineLength < selectionEnd ) {
			flags |= SWT.LAST_LINE_SELECTION;
		}
		layout.draw(gc, paintX, paintY, start, end - 1, selectionFg, selectionBg, flags);
	}

	// draw objects
	Bullet bullet = null;
	int bulletIndex = -1;
	if (bullets != null) {
		if (bulletsIndices != null) {
			int index = lineIndex - topIndex;
			if (0 <= index && index < CACHE_SIZE) {
				bullet = bullets[index];
				bulletIndex = bulletsIndices[index];
			}
		} else {
			for (Bullet b : bullets) {
				bullet = b;
				bulletIndex = bullet.indexOf(lineIndex);
				if (bulletIndex != -1) break;
			}
		}
	}
	if (bulletIndex != -1 && bullet != null) {
		FontMetrics metrics = layout.getLineMetrics(0);
		int lineAscent = metrics.getAscent() + metrics.getLeading();
		if (bullet.type == ST.BULLET_CUSTOM) {
			bullet.style.start = lineOffset;
			styledText.paintObject(gc, paintX, paintY, lineAscent, metrics.getDescent(), bullet.style, bullet, bulletIndex);
		} else {
			drawBullet(bullet, gc, paintX, paintY, bulletIndex, lineAscent, metrics.getDescent());
		}
	}
	TextStyle[] styles = layout.getStyles();
	int[] ranges = null;
	for (int i = 0; i < styles.length; i++) {
		if (styles[i].metrics != null) {
			if (ranges == null) ranges = layout.getRanges();
			int start = ranges[i << 1];
			int length = ranges[(i << 1) + 1] - start + 1;
			Point point = layout.getLocation(start, false);
			FontMetrics metrics = layout.getLineMetrics(layout.getLineIndex(start));
			StyleRange style = (StyleRange)((StyleRange)styles[i]).clone();
			style.start = start + lineOffset;
			style.length = length;
			int lineAscent = metrics.getAscent() + metrics.getLeading();
			styledText.paintObject(gc, point.x + paintX, point.y + paintY, lineAscent, metrics.getDescent(), style, null, 0);
		}
	}
	disposeTextLayout(layout);
	return height;
}
int getBaseline() {
	return ascent;
}
Font getFont(int style) {
	switch (style) {
		case SWT.BOLD:
			if (boldFont != null) return boldFont;
			return boldFont = new Font(device, getFontData(style));
		case SWT.ITALIC:
			if (italicFont != null) return italicFont;
			return italicFont = new Font(device, getFontData(style));
		case SWT.BOLD | SWT.ITALIC:
			if (boldItalicFont != null) return boldItalicFont;
			return boldItalicFont = new Font(device, getFontData(style));
		default:
			return regularFont;
	}
}
FontData[] getFontData(int style) {
	FontData[] fontDatas = regularFont.getFontData();
	for (FontData fontData : fontDatas) {
		fontData.setStyle(style);
	}
	return fontDatas;
}
int getHeight () {
	int defaultLineHeight = getLineHeight();
	if (styledText.isFixedLineHeight()) {
		return lineCount * defaultLineHeight + styledText.topMargin + styledText.bottomMargin;
	}
	int totalHeight = 0;
	int width = styledText.getWrapWidth();
	for (int i = 0; i < lineCount; i++) {
		LineSizeInfo line = getLineSize(i);
		int height = line.height;
		if (line.needsRecalculateHeight()) {
			if (width > 0) {
				int length = content.getLine(i).length();
				height = ((length * averageCharWidth / width) + 1) * defaultLineHeight;
			} else {
				height = defaultLineHeight;
			}
		}
		totalHeight += height;
	}
	return totalHeight + styledText.topMargin + styledText.bottomMargin;
}
boolean hasLink(int offset) {
	if (offset == -1) return false;
	int lineIndex = content.getLineAtOffset(offset);
	int lineOffset = content.getOffsetAtLine(lineIndex);
	String line = content.getLine(lineIndex);
	StyledTextEvent event = styledText.getLineStyleData(lineOffset, line);
	if (event != null) {
		StyleRange[] styles = event.styles;
		if (styles != null) {
			int[] ranges = event.ranges;
			if (ranges != null) {
				for (int i = 0; i < ranges.length; i+=2) {
					if (ranges[i] <= offset && offset < ranges[i] + ranges[i+1] && styles[i >> 1].underline && styles[i >> 1].underlineStyle == SWT.UNDERLINE_LINK) {
						return true;
					}
				}
			} else {
				for (StyleRange style : styles) {
					if (style.start <= offset && offset < style.start + style.length && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) {
						return true;
					}
				}
			}
		}
	}  else {
		if (ranges != null) {
			int rangeCount = styleCount << 1;
			int index = getRangeIndex(offset, -1, rangeCount);
			if (index >= rangeCount) return false;
			int rangeStart = ranges[index];
			int rangeLength = ranges[index + 1];
			StyleRange rangeStyle = styles[index >> 1];
			if (rangeStart <= offset && offset < rangeStart + rangeLength && rangeStyle.underline && rangeStyle.underlineStyle == SWT.UNDERLINE_LINK) {
				return true;
			}
		}
	}
	return false;
}
int getLineAlignment(int index, int defaultAlignment) {
	if (lines == null) return defaultAlignment;
	LineInfo info = lines[index];
	if (info != null && (info.flags & ALIGNMENT) != 0) {
		return info.alignment;
	}
	return defaultAlignment;
}
Color getLineBackground(int index, Color defaultBackground) {
	if (lines == null) return defaultBackground;
	LineInfo info = lines[index];
	if (info != null && (info.flags & BACKGROUND) != 0) {
		return info.background;
	}
	return defaultBackground;
}
Bullet getLineBullet (int index, Bullet defaultBullet) {
	if (bullets == null) return defaultBullet;
	if (bulletsIndices != null) return defaultBullet;
	for (Bullet bullet : bullets) {
		if (bullet.indexOf(index) != -1) return bullet;
	}
	return defaultBullet;
}
int getLineHeight() {
	return ascent + descent;
}
int getLineHeight(int lineIndex) {
	LineSizeInfo line = getLineSize(lineIndex);
	if (line.needsRecalculateHeight()) {
		// here we are in "variable line height", the call of calculate which uses TextLayout can be very slow
		// check if line can use the default line height.
		if (isVariableHeight(lineIndex)) {
			calculate(lineIndex, 1);
		} else {
			line.height = getLineHeight() + getLineSpacing(lineIndex);
		}
	}
	return line.height;
}
/**
 * Returns true if the given line can use the default line height and false
 * otherwise.
 *
 * @param lineIndex
 *            line index
 * @return true if the given line can use the default line height and false
 *         otherwise.
 */
private boolean isVariableHeight(int lineIndex) {
	if (styledText.isWordWrap()) {
		// In word wrap mode, the line height must be recomputed with TextLayout
		return true;
	}
	StyleRange[] styles = getStylesForLine(lineIndex);
	if (styles != null) {
		for (StyleRange style : styles) {
			if (style.isVariableHeight()) {
				// style is variable height
				return true;
			}
		}
	}
	return false;
}
/**
 * returns true if the given line index defines custom line spacing and false
 * otherwise.
 *
 * @param lineIndex
 *            the line index.
 * @return true if the given line index defines custom line spacing and false
 *         otherwise.
 */
private int getLineSpacing(int lineIndex) {
	if (styledText.lineSpacing > 0) {
		return styledText.lineSpacing;
	} else if (lineSpacingProvider != null) {
		Integer lineSpacing = lineSpacingProvider.getLineSpacing(lineIndex);
		if (lineSpacing != null) {
			return lineSpacing;
		}
	}
	return 0;
}
/**
 * Returns styles range for the given line index and null otherwise.
 *
 * @param lineIndex
 *            the line index.
 * @return styles range for the given line index and null otherwise.
 */
private StyleRange[] getStylesForLine(int lineIndex) {
	int start = styledText.getOffsetAtLine(lineIndex);
	int length = styledText.getLine(lineIndex).length();
	return getStyleRanges(start, length, false);
}
int getLineIndent(int index, int defaultIndent) {
	if (lines == null) return defaultIndent;
	LineInfo info = lines[index];
	if (info != null && (info.flags & INDENT) != 0) {
		return info.indent;
	}
	return defaultIndent;
}
int getLineVerticalIndent(int index) {
	if (lines == null) return 0;
	LineInfo info = lines[index];
	if (info != null && (info.flags & VERTICAL_INDENT) != 0) {
		return info.verticalIndent;
	}
	return 0;
}
int getLineWrapIndent(int index, int defaultWrapIndent) {
	if (lines == null) return defaultWrapIndent;
	LineInfo info = lines[index];
	if (info != null && (info.flags & WRAP_INDENT) != 0) {
		return info.wrapIndent;
	}
	return defaultWrapIndent;
}
boolean getLineJustify(int index, boolean defaultJustify) {
	if (lines == null) return defaultJustify;
	LineInfo info = lines[index];
	if (info != null && (info.flags & JUSTIFY) != 0) {
		return info.justify;
	}
	return defaultJustify;
}
int[] getLineTabStops(int index, int[] defaultTabStops) {
	if (lines == null) return defaultTabStops;
	LineInfo info = lines[index];
	if (info != null && (info.flags & TABSTOPS) != 0) {
		return info.tabStops;
	}
	return defaultTabStops;
}
StyledTextLineSpacingProvider getLineSpacingProvider() {
	return lineSpacingProvider;
}
int getRangeIndex(int offset, int low, int high) {
	if (styleCount == 0) return 0;
	if (ranges != null)  {
		while (high - low > 2) {
			int index = ((high + low) / 2) / 2 * 2;
			int end = ranges[index] + ranges[index + 1];
			if (end > offset) {
				high = index;
			} else {
				low = index;
			}
		}
	} else {
		while (high - low > 1) {
			int index = ((high + low) / 2);
			int end = styles[index].start + styles[index].length;
			if (end > offset) {
				high = index;
			} else {
				low = index;
			}
		}
	}
	return high;
}
int[] getRanges(int start, int length) {
	if (length == 0) return null;
	int[] newRanges;
	int end = start + length - 1;
	if (ranges != null) {
		int rangeCount = styleCount << 1;
		int rangeStart = getRangeIndex(start, -1, rangeCount);
		if (rangeStart >= rangeCount) return null;
		if (ranges[rangeStart] > end) return null;
		int rangeEnd = Math.min(rangeCount - 2, getRangeIndex(end, rangeStart - 1, rangeCount));
		if (ranges[rangeEnd] > end) rangeEnd = Math.max(rangeStart, rangeEnd - 2);
		newRanges = new int[rangeEnd - rangeStart + 2];
		System.arraycopy(ranges, rangeStart, newRanges, 0, newRanges.length);
	} else {
		int rangeStart = getRangeIndex(start, -1, styleCount);
		if (rangeStart >= styleCount) return null;
		if (styles[rangeStart].start > end) return null;
		int rangeEnd = Math.min(styleCount - 1, getRangeIndex(end, rangeStart - 1, styleCount));
		if (styles[rangeEnd].start > end) rangeEnd = Math.max(rangeStart, rangeEnd - 1);
		newRanges = new int[(rangeEnd - rangeStart + 1) << 1];
		for (int i = rangeStart, j = 0; i <= rangeEnd; i++, j += 2) {
			StyleRange style = styles[i];
			newRanges[j] = style.start;
			newRanges[j + 1] = style.length;
		}
	}
	if (start > newRanges[0]) {
		newRanges[1] = newRanges[0] + newRanges[1] - start;
		newRanges[0] = start;
	}
	if (end < newRanges[newRanges.length - 2] + newRanges[newRanges.length - 1] - 1) {
		newRanges[newRanges.length - 1] = end - newRanges[newRanges.length - 2] + 1;
	}
	return newRanges;
}
StyleRange[] getStyleRanges(int start, int length, boolean includeRanges) {
	if (length == 0) return null;
	StyleRange[] newStyles;
	int end = start + length - 1;
	if (ranges != null) {
		int rangeCount = styleCount << 1;
		int rangeStart = getRangeIndex(start, -1, rangeCount);
		if (rangeStart >= rangeCount) return null;
		if (ranges[rangeStart] > end) return null;
		int rangeEnd = Math.min(rangeCount - 2, getRangeIndex(end, rangeStart - 1, rangeCount));
		if (ranges[rangeEnd] > end) rangeEnd = Math.max(rangeStart, rangeEnd - 2);
		newStyles = new StyleRange[((rangeEnd - rangeStart) >> 1) + 1];
		if (includeRanges) {
			for (int i = rangeStart, j = 0; i <= rangeEnd; i += 2, j++) {
				newStyles[j] = (StyleRange)styles[i >> 1].clone();
				newStyles[j].start = ranges[i];
				newStyles[j].length = ranges[i + 1];
			}
		} else {
			System.arraycopy(styles, rangeStart >> 1, newStyles, 0, newStyles.length);
		}
	} else {
		int rangeStart = getRangeIndex(start, -1, styleCount);
		if (rangeStart >= styleCount) return null;
		if (styles[rangeStart].start > end) return null;
		int rangeEnd = Math.min(styleCount - 1, getRangeIndex(end, rangeStart - 1, styleCount));
		if (styles[rangeEnd].start > end) rangeEnd = Math.max(rangeStart, rangeEnd - 1);
		newStyles = new StyleRange[rangeEnd - rangeStart + 1];
		System.arraycopy(styles, rangeStart, newStyles, 0, newStyles.length);
	}
	if (includeRanges || ranges == null) {
		StyleRange style = newStyles[0];
		if (start > style.start) {
			newStyles[0] = style = (StyleRange)style.clone();
			style.length = style.start + style.length - start;
			style.start = start;
		}
		style = newStyles[newStyles.length - 1];
		if (end < style.start + style.length - 1) {
			newStyles[newStyles.length - 1] = style = (StyleRange)style.clone();
			style.length = end - style.start + 1;
		}
	}
	return newStyles;
}
StyleRange getStyleRange(StyleRange style) {
	if (style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) hasLinks = true;
	if (style.start == 0 && style.length == 0 && style.fontStyle == SWT.NORMAL) return style;
	StyleRange clone = (StyleRange)style.clone();
	clone.start = clone.length = 0;
	clone.fontStyle = SWT.NORMAL;
	if (clone.font == null) clone.font = getFont(style.fontStyle);
	return clone;
}
TextLayout getTextLayout(int lineIndex) {
	if (lineSpacingProvider == null) {
		return getTextLayout(lineIndex, styledText.getOrientation(), styledText.getWrapWidth(), styledText.lineSpacing);
	}
	// Compute line spacing for the given line index.
	int newLineSpacing = styledText.lineSpacing;
	Integer spacing = lineSpacingProvider.getLineSpacing(lineIndex);
	if (spacing != null && spacing.intValue() >= 0) {
		newLineSpacing = spacing;
	}
	// Check if line spacing has not changed
	if (isSameLineSpacing(lineIndex, newLineSpacing)) {
		return getTextLayout(lineIndex, styledText.getOrientation(), styledText.getWrapWidth(), newLineSpacing);
	}
	// Get text layout with original StyledText line spacing.
	TextLayout layout = getTextLayout(lineIndex, styledText.getOrientation(), styledText.getWrapWidth(),
			styledText.lineSpacing);
	if (layout.getSpacing() != newLineSpacing) {
		layout.setSpacing(newLineSpacing);
		if (lineSpacingComputing) {
			return layout;
		}
		try {
			/* Call of resetCache, setCaretLocation, redraw call getTextLayout method
			 * To avoid having stack overflow, lineSpacingComputing flag is used to call
			 * resetCache, setCaretLocation, redraw methods only at the end of the compute of all lines spacing.
			 */
			lineSpacingComputing = true;
			styledText.resetCache(lineIndex, 1);
			styledText.setCaretLocation();
			styledText.redraw();
		} finally {
			lineSpacingComputing = false;
		}
	}
	return layout;
}
boolean isSameLineSpacing(int lineIndex, int newLineSpacing) {
	if (layouts == null) {
		return false;
	}
	int layoutIndex = lineIndex - topIndex;
	if (0 <= layoutIndex && layoutIndex < layouts.length) {
		TextLayout layout = layouts[layoutIndex];
		return layout != null && !layout.isDisposed() && layout.getSpacing() == newLineSpacing;
	}
	return false;
}

private static final class StyleEntry {
	public final int start;
	public final int end;
	public final TextStyle style;

	public StyleEntry(TextStyle style, int start, int end) {
		this.style = style;
		this.start = start;
		this.end = end;
	}
}

TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpacing) {
	TextLayout layout = null;
	if (styledText != null) {
		int topIndex = styledText.topIndex > 0 ? styledText.topIndex - 1 : 0;
		if (layouts == null || topIndex != this.topIndex) {
			TextLayout[] newLayouts = new TextLayout[CACHE_SIZE];
			if (layouts != null) {
				for (int i = 0; i < layouts.length; i++) {
					if (layouts[i] != null) {
						int layoutIndex = (i + this.topIndex) - topIndex;
						if (0 <= layoutIndex && layoutIndex < newLayouts.length) {
							newLayouts[layoutIndex] = layouts[i];
						} else {
							layouts[i].dispose();
						}
					}
				}
			}
			if (bullets != null && bulletsIndices != null && topIndex != this.topIndex) {
				int delta = topIndex - this.topIndex;
				if (delta > 0) {
					if (delta < bullets.length) {
						System.arraycopy(bullets, delta, bullets, 0, bullets.length - delta);
						System.arraycopy(bulletsIndices, delta, bulletsIndices, 0, bulletsIndices.length - delta);
					}
					int startIndex = Math.max(0, bullets.length - delta);
					for (int i = startIndex; i < bullets.length; i++) bullets[i] = null;
				} else {
					if (-delta < bullets.length) {
						System.arraycopy(bullets, 0, bullets, -delta, bullets.length + delta);
						System.arraycopy(bulletsIndices, 0, bulletsIndices, -delta, bulletsIndices.length + delta);
					}
					int endIndex = Math.min(bullets.length, -delta);
					for (int i = 0; i < endIndex; i++) bullets[i] = null;
				}
			}
			this.topIndex = topIndex;
			layouts = newLayouts;
		}
		if (layouts != null) {
			int layoutIndex = lineIndex - topIndex;
			if (0 <= layoutIndex && layoutIndex < layouts.length) {
				layout = layouts[layoutIndex];
				if (layout != null) {
					// Bug 520374: lineIndex can be >= linesSize.length
					if(lineIndex < lineSizes.length && getLineSize(lineIndex).canLayout()) {
						return layout;
					}
				} else {
					layout = layouts[layoutIndex] = new TextLayout(device);
				}
			}
		}
	}
	if (layout == null) layout = new TextLayout(device);
	String line = content.getLine(lineIndex);
	int lineOffset = content.getOffsetAtLine(lineIndex);
	int[] segments = null;
	char[] segmentChars = null;
	int indent = 0;
	int wrapIndent = 0;
	int verticalIndent = 0;
	int alignment = SWT.LEFT;
	int textDirection = orientation;
	boolean justify = false;
	int[] tabs = {tabWidth};
	Bullet bullet = null;
	int[] ranges = null;
	StyleRange[] styles = null;
	int rangeStart = 0, styleCount = 0;
	StyledTextEvent event = null;
	if (styledText != null) {
		event = styledText.getBidiSegments(lineOffset, line);
		if (event != null) {
			segments = event.segments;
			segmentChars = event.segmentsChars;
		}
		event = styledText.getLineStyleData(lineOffset, line);
		indent = styledText.indent;
		wrapIndent = styledText.wrapIndent;
		alignment = styledText.alignment;
		if (styledText.isAutoDirection()) {
			textDirection = SWT.AUTO_TEXT_DIRECTION;
		} else if ((styledText.getStyle() & SWT.FLIP_TEXT_DIRECTION) != 0) {
			textDirection = orientation == SWT.RIGHT_TO_LEFT ? SWT.LEFT_TO_RIGHT : SWT.RIGHT_TO_LEFT;
		}
		justify = styledText.justify;
		if (styledText.tabs != null) tabs = styledText.tabs;
	}
	if (event != null) {
		indent = event.indent;
		verticalIndent = event.verticalIndent;
		wrapIndent = event.wrapIndent;
		alignment = event.alignment;
		justify = event.justify;
		bullet = event.bullet;
		ranges = event.ranges;
		styles = event.styles;
		if (event.tabStops != null) tabs = event.tabStops;
		if (styles != null) {
			styleCount = styles.length;
			if (styledText.isFixedLineHeight()) {
				for (int i = 0; i < styleCount; i++) {
					if (styles[i].isVariableHeight()) {
						styledText.hasStyleWithVariableHeight = true;
						styledText.verticalScrollOffset = -1;
						styledText.redraw();
						break;
					}
				}
			}
		}
		if (bullets == null || bulletsIndices == null) {
			bullets = new Bullet[CACHE_SIZE];
			bulletsIndices = new int[CACHE_SIZE];
		}
		int index = lineIndex - topIndex;
		if (0 <= index && index < CACHE_SIZE) {
			bullets[index] = bullet;
			bulletsIndices[index] = event.bulletIndex;
		}
	} else {
		if (lines != null) {
			LineInfo info = lines[lineIndex];
			if (info != null) {
				if ((info.flags & INDENT) != 0) indent = info.indent;
				if ((info.flags & VERTICAL_INDENT) != 0) verticalIndent = info.verticalIndent;
				if ((info.flags & WRAP_INDENT) != 0) wrapIndent = info.wrapIndent;
				if ((info.flags & ALIGNMENT) != 0) alignment = info.alignment;
				if ((info.flags & JUSTIFY) != 0) justify = info.justify;
				if ((info.flags & SEGMENTS) != 0) segments = info.segments;
				if ((info.flags & SEGMENT_CHARS) != 0) segmentChars = info.segmentsChars;
				if ((info.flags & TABSTOPS) != 0) tabs = info.tabStops;
			}
		}
		if (bulletsIndices != null) {
			bullets = null;
			bulletsIndices = null;
		}
		if (bullets != null) {
			for (Bullet b : bullets) {
				if (b.indexOf(lineIndex) != -1) {
					bullet = b;
					break;
				}
			}
		}
		ranges = this.ranges;
		styles = this.styles;
		styleCount = this.styleCount;
		if (ranges != null) {
			rangeStart = getRangeIndex(lineOffset, -1, styleCount << 1);
		} else {
			rangeStart = getRangeIndex(lineOffset, -1, styleCount);
		}
	}
	if (bullet != null) {
		StyleRange style = bullet.style;
		GlyphMetrics metrics = style.metrics;
		indent += metrics.width;
	}

	// prepare styles, as it may change the line content, do it before calling layout.setText()
	// This needs to happen early to handle the case of GlyphMetrics on \t.
	// The root cause is that TextLayout doesn't return the right value for the bounds when
	// GlyphMetrics are applied on \t. A better fix could be implemented directly in (all 3)
	// TextLayout classes.
	List<StyleEntry> styleEntries = new ArrayList<>();
	int lastOffset = 0;
	int length = line.length();
	if (styles != null) {
		if (ranges != null) {
			int rangeCount = styleCount << 1;
			for (int i = rangeStart; i < rangeCount; i += 2) {
				int start, end;
				if (lineOffset > ranges[i]) {
					start = 0;
					end = Math.min (length, ranges[i + 1] - lineOffset + ranges[i]);
				} else {
					start = ranges[i] - lineOffset;
					end = Math.min(length, start + ranges[i + 1]);
				}
				if (start >= length) break;
				if (lastOffset < start) {
					styleEntries.add(new StyleEntry(null, lastOffset, start - 1));
				}
				TextStyle style = getStyleRange(styles[i >> 1]);
				int endIndex = Math.max(start, Math.min(length, end + 1));
				if (style.metrics != null && line.substring(start, endIndex).contains("\t")) {
					line =
						line.substring(0, start) +
						line.substring(start, endIndex).replace('\t', ' ') +
						(end < line.length() ? line.substring(end + 1, line.length()) : "");
				}
				styleEntries.add(new StyleEntry(style, start, end));
				lastOffset = Math.max(lastOffset, end);
			}
		} else {
			for (int i = rangeStart; i < styleCount; i++) {
				int start, end;
				if (lineOffset > styles[i].start) {
					start = 0;
					end = Math.min (length, styles[i].length - lineOffset + styles[i].start);
				} else {
					start = styles[i].start - lineOffset;
					end = Math.min(length, start + styles[i].length);
				}
				if (start >= length) break;
				if (lastOffset < start) {
					styleEntries.add(new StyleEntry(null, lastOffset, start - 1));
				}
				TextStyle style = getStyleRange(styles[i]);
				int endIndex = Math.max(start, Math.min(length, end + 1));
				if (style.metrics != null && line.substring(start, endIndex).contains("\t")) {
					line =
						line.substring(0, start) +
						line.substring(start, endIndex).replace('\t', ' ') +
						(end < line.length() ? line.substring(end + 1, line.length()) : "");
				}
				styleEntries.add(new StyleEntry(style, start, end));
				lastOffset = Math.max(lastOffset, end);
			}
		}
	}
	if (lastOffset < length) styleEntries.add(new StyleEntry(null, lastOffset, length));

	layout.setFont(regularFont);
	layout.setAscent(ascent);
	layout.setDescent(descent);
	layout.setText(line);
	layout.setOrientation(orientation);
	layout.setSegments(segments);
	layout.setSegmentsChars(segmentChars);
	layout.setWidth(width);
	layout.setSpacing(lineSpacing);
	layout.setTabs(tabs);
	layout.setDefaultTabWidth(tabLength);
	layout.setIndent(indent);
	layout.setVerticalIndent(verticalIndent);
	layout.setWrapIndent(wrapIndent);
	layout.setAlignment(alignment);
	layout.setJustify(justify);
	layout.setTextDirection(textDirection);
	// apply styles, must be done after layout.setText()
	for (StyleEntry styleEntry : styleEntries) {
		layout.setStyle(styleEntry.style, styleEntry.start, styleEntry.end);
	}

	if (styledText != null && styledText.ime != null) {
		IME ime = styledText.ime;
		int compositionOffset = ime.getCompositionOffset();
		if (compositionOffset != -1) {
			int commitCount = ime.getCommitCount();
			int compositionLength = ime.getText().length();
			if (compositionLength != commitCount) {
				int compositionLine = content.getLineAtOffset(compositionOffset);
				if (compositionLine == lineIndex) {
					int[] imeRanges = ime.getRanges();
					TextStyle[] imeStyles = ime.getStyles();
					if (imeRanges.length > 0) {
						for (int i = 0; i < imeStyles.length; i++) {
							int start = imeRanges[i*2] - lineOffset;
							int end = imeRanges[i*2+1] - lineOffset;
							TextStyle imeStyle = imeStyles[i], userStyle;
							for (int j = start; j <= end; j++) {
								if (!(0 <= j && j < length)) break;
								userStyle = layout.getStyle(cap(layout, j));
								if (userStyle == null && j > 0) userStyle = layout.getStyle(cap(layout, j - 1));
								if (userStyle == null && j + 1 < length) userStyle = layout.getStyle(cap(layout, j + 1));
								if (userStyle == null) {
									layout.setStyle(imeStyle, j, j);
								} else {
									TextStyle newStyle = new TextStyle(imeStyle);
									if (newStyle.font == null) newStyle.font = userStyle.font;
									if (newStyle.foreground == null) newStyle.foreground = userStyle.foreground;
									if (newStyle.background == null) newStyle.background = userStyle.background;
									layout.setStyle(newStyle, j, j);
								}
							}
						}
					} else {
						int start = compositionOffset - lineOffset;
						int end = start + compositionLength - 1;
						TextStyle userStyle = layout.getStyle(cap(layout, start));
						if (userStyle == null) {
							if (start > 0) userStyle = layout.getStyle(cap(layout, start - 1));
							if (userStyle == null && end + 1 < length) userStyle = layout.getStyle(cap(layout, end + 1));
							if (userStyle != null) {
								TextStyle newStyle = new TextStyle();
								newStyle.font = userStyle.font;
								newStyle.foreground = userStyle.foreground;
								newStyle.background = userStyle.background;
								layout.setStyle(newStyle, start, end);
							}
						}
					}
				}
			}
		}
	}

	if (styledText != null && styledText.isFixedLineHeight()) {
		int index = -1;
		int lineCount = layout.getLineCount();
		int height = getLineHeight();
		for (int i = 0; i < lineCount; i++) {
			int lineHeight = layout.getLineBounds(i).height;
			if (lineHeight > height) {
				height = lineHeight;
				index = i;
			}
		}
		if (index != -1) {
			FontMetrics metrics = layout.getLineMetrics(index);
			ascent = metrics.getAscent() + metrics.getLeading();
			descent = metrics.getDescent();
			if (layouts != null) {
				for (TextLayout l : layouts) {
					if (l != null && l != layout) {
						l.setAscent(ascent);
						l.setDescent(descent);
					}
				}
			}
			styledText.calculateScrollBars();
			if (styledText.verticalScrollOffset != 0) {
				int topIndex = styledText.topIndex;
				int topIndexY = styledText.topIndexY;
				int lineHeight = getLineHeight();
				int newVerticalScrollOffset;
				if (topIndexY >= 0) {
					newVerticalScrollOffset = (topIndex - 1) * lineHeight + lineHeight - topIndexY;
				} else {
					newVerticalScrollOffset = topIndex * lineHeight - topIndexY;
				}
				styledText.scrollVertical(newVerticalScrollOffset - styledText.verticalScrollOffset, true);
			}
			if (styledText.isBidiCaret()) styledText.createCaretBitmaps();
			styledText.caretDirection = SWT.NULL;
			styledText.setCaretLocation();
			styledText.redraw();
		}
	}
	return layout;
}
int getWidth() {
	return maxWidth;
}
void reset() {
	if (layouts != null) {
		for (TextLayout layout : layouts) {
			if (layout != null) layout.dispose();
		}
		layouts = null;
	}
	topIndex = -1;
	stylesSetCount = styleCount = lineCount = 0;
	ranges = null;
	styles = null;
	stylesSet = null;
	lines = null;
	lineSizes = null;
	bullets = null;
	bulletsIndices = null;
	redrawLines = null;
	hasLinks = false;
}
void reset(int startLine, int lineCount) {
	int endLine = startLine + lineCount;
	if (startLine < 0 || endLine > lineSizes.length) return;
	SortedSet<Integer> lines = new TreeSet<>();
	for (int i = startLine; i < endLine; i++) {
		lines.add(Integer.valueOf(i));
	}
	reset(lines);
}
void reset(Set<Integer> lines) {
	if (lines == null || lines.isEmpty()) return;
	int resetLineCount = 0;
	for (Integer line : lines) {
		if (line >= 0 || line < lineCount) {
			resetLineCount++;
			getLineSize(line.intValue()).resetSize();
		}
	}
	if (lines.contains(Integer.valueOf(maxWidthLineIndex))) {
		maxWidth = 0;
		maxWidthLineIndex = -1;
		if (resetLineCount != this.lineCount) {
			for (int i = 0; i < this.lineCount; i++) {
				LineSizeInfo lineSize = getLineSize(i);
				if (lineSize.width > maxWidth) {
					maxWidth = lineSize.width;
					maxWidthLineIndex = i;
				}
			}
		}
	}
}
void setContent(StyledTextContent content) {
	reset();
	this.content = content;
	lineCount = content.getLineCount();
	lineSizes = new LineSizeInfo[lineCount];
	maxWidth = 0;
	maxWidthLineIndex = -1;
	reset(0, lineCount);
}
void setFont(Font font, int tabs) {
	TextLayout layout = new TextLayout(device);
	layout.setFont(regularFont);
	tabLength = tabs;
	if (font != null) {
		if (boldFont != null) boldFont.dispose();
		if (italicFont != null) italicFont.dispose();
		if (boldItalicFont != null) boldItalicFont.dispose();
		boldFont = italicFont = boldItalicFont = null;
		regularFont = font;
		layout.setText("    ");
		layout.setFont(font);
		layout.setStyle(new TextStyle(getFont(SWT.NORMAL), null, null), 0, 0);
		layout.setStyle(new TextStyle(getFont(SWT.BOLD), null, null), 1, 1);
		layout.setStyle(new TextStyle(getFont(SWT.ITALIC), null, null), 2, 2);
		layout.setStyle(new TextStyle(getFont(SWT.BOLD | SWT.ITALIC), null, null), 3, 3);
		FontMetrics metrics = layout.getLineMetrics(0);
		ascent = metrics.getAscent() + metrics.getLeading();
		descent = metrics.getDescent();
		boldFont.dispose();
		italicFont.dispose();
		boldItalicFont.dispose();
		boldFont = italicFont = boldItalicFont = null;
	}
	layout.dispose();
	layout = new TextLayout(device);
	layout.setFont(regularFont);
	StringBuilder tabBuffer = new StringBuilder(tabs);
	for (int i = 0; i < tabs; i++) {
		tabBuffer.append(' ');
	}
	layout.setText(tabBuffer.toString());
	tabWidth = layout.getBounds().width;
	layout.dispose();
	if (styledText != null) {
		GC gc = new GC(styledText);
		averageCharWidth = (int) gc.getFontMetrics().getAverageCharacterWidth();
		fixedPitch = gc.stringExtent("l").x == gc.stringExtent("W").x; //$NON-NLS-1$ //$NON-NLS-2$
		gc.dispose();
	}
}
void setLineAlignment(int startLine, int count, int alignment) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= ALIGNMENT;
		lines[i].alignment = alignment;
	}
}
void setLineBackground(int startLine, int count, Color background) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= BACKGROUND;
		lines[i].background = background;
	}
}
void setLineBullet(int startLine, int count, Bullet bullet) {
	if (bulletsIndices != null) {
		bulletsIndices = null;
		bullets = null;
	}
	if (bullets == null) {
		if (bullet == null) return;
		bullets = new Bullet[1];
		bullets[0] = bullet;
	}
	int index = 0;
	while (index < bullets.length) {
		if (bullet == bullets[index]) break;
		index++;
	}
	if (bullet != null) {
		if (index == bullets.length) {
			Bullet[] newBulletsList = new Bullet[bullets.length + 1];
			System.arraycopy(bullets, 0, newBulletsList, 0, bullets.length);
			newBulletsList[index] = bullet;
			bullets = newBulletsList;
		}
		bullet.addIndices(startLine, count);
	} else {
		updateBullets(startLine, count, 0, false);
		styledText.redrawLinesBullet(redrawLines);
		redrawLines = null;
	}
}
void setLineIndent(int startLine, int count, int indent) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= INDENT;
		lines[i].indent = indent;
	}
}
void setLineVerticalIndent(int lineIndex, int verticalLineIndent) {
	if (lines == null)
		lines = new LineInfo[lineCount];
	if (lines[lineIndex] == null) {
		lines[lineIndex] = new LineInfo();
	}
	lines[lineIndex].flags |= VERTICAL_INDENT;
	lines[lineIndex].verticalIndent = verticalLineIndent;
}
void setLineWrapIndent(int startLine, int count, int wrapIndent) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= WRAP_INDENT;
		lines[i].wrapIndent = wrapIndent;
	}
}
void setLineJustify(int startLine, int count, boolean justify) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= JUSTIFY;
		lines[i].justify = justify;
	}
}
void setLineSegments(int startLine, int count, int[] segments) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= SEGMENTS;
		lines[i].segments = segments;
	}
}
void setLineSegmentChars(int startLine, int count, char[] segmentChars) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= SEGMENT_CHARS;
		lines[i].segmentsChars = segmentChars;
	}
}
void setLineTabStops(int startLine, int count, int[] tabStops) {
	if (lines == null) lines = new LineInfo[lineCount];
	for (int i = startLine; i < startLine + count; i++) {
		if (lines[i] == null) {
			lines[i] = new LineInfo();
		}
		lines[i].flags |= TABSTOPS;
		lines[i].tabStops = tabStops;
	}
}
void setLineSpacingProvider(StyledTextLineSpacingProvider lineSpacingProvider) {
	this.lineSpacingProvider = lineSpacingProvider;
}
void setStyleRanges (int[] newRanges, StyleRange[] newStyles) {
	if (newStyles == null) {
		stylesSetCount = styleCount = 0;
		ranges = null;
		styles = null;
		stylesSet = null;
		hasLinks = false;
		return;
	}
	if (newRanges == null && COMPACT_STYLES) {
		newRanges = new int[newStyles.length << 1];
		StyleRange[] tmpStyles = new StyleRange[newStyles.length];
		if (stylesSet == null) stylesSet = new StyleRange[4];
		for (int i = 0, j = 0; i < newStyles.length; i++) {
			StyleRange newStyle = newStyles[i];
			newRanges[j++] = newStyle.start;
			newRanges[j++] = newStyle.length;
			int index = 0;
			while (index < stylesSetCount) {
				if (stylesSet[index].similarTo(newStyle)) break;
				index++;
			}
			if (index == stylesSetCount) {
				if (stylesSetCount == stylesSet.length) {
					StyleRange[] tmpStylesSet = new StyleRange[stylesSetCount + 4];
					System.arraycopy(stylesSet, 0, tmpStylesSet, 0, stylesSetCount);
					stylesSet = tmpStylesSet;
				}
				stylesSet[stylesSetCount++] = newStyle;
			}
			tmpStyles[i] = stylesSet[index];
		}
		newStyles = tmpStyles;
	}

	if (styleCount == 0) {
		if (newRanges != null) {
			ranges = new int[newRanges.length];
			System.arraycopy(newRanges, 0, ranges, 0, ranges.length);
		}
		styles = new StyleRange[newStyles.length];
		System.arraycopy(newStyles, 0, styles, 0, styles.length);
		styleCount = newStyles.length;
		return;
	}
	if (newRanges != null && ranges == null) {
		ranges = new int[styles.length << 1];
		for (int i = 0, j = 0; i < styleCount; i++) {
			ranges[j++] = styles[i].start;
			ranges[j++] = styles[i].length;
		}
	}
	if (newRanges == null && ranges != null) {
		newRanges = new int[newStyles.length << 1];
		for (int i = 0, j = 0; i < newStyles.length; i++) {
			newRanges[j++] = newStyles[i].start;
			newRanges[j++] = newStyles[i].length;
		}
	}
	if (ranges != null) {
		int rangeCount = styleCount << 1;
		int start = newRanges[0];
		int modifyStart = getRangeIndex(start, -1, rangeCount), modifyEnd;
		boolean insert = modifyStart == rangeCount;
		if (!insert) {
			int end = newRanges[newRanges.length - 2] + newRanges[newRanges.length - 1];
			modifyEnd = getRangeIndex(end, modifyStart - 1, rangeCount);
			insert = modifyStart == modifyEnd && ranges[modifyStart] >= end;
		}
		if (insert) {
			addMerge(newRanges, newStyles, newRanges.length, modifyStart, modifyStart);
			return;
		}
		modifyEnd = modifyStart;
		int[] mergeRanges = new int[6];
		StyleRange[] mergeStyles = new StyleRange[3];
		for (int i = 0; i < newRanges.length; i += 2) {
			int newStart = newRanges[i];
			int newEnd = newStart + newRanges[i + 1];
			if (newStart == newEnd) continue;
			int modifyLast = 0, mergeCount = 0;
			while (modifyEnd < rangeCount) {
				if (newStart >= ranges[modifyStart] + ranges[modifyStart + 1]) modifyStart += 2;
				if (ranges[modifyEnd] + ranges[modifyEnd + 1] > newEnd) break;
				modifyEnd += 2;
			}
			if (ranges[modifyStart] < newStart && newStart < ranges[modifyStart] + ranges[modifyStart + 1]) {
				mergeStyles[mergeCount >> 1] = styles[modifyStart >> 1];
				mergeRanges[mergeCount] = ranges[modifyStart];
				mergeRanges[mergeCount + 1] = newStart - ranges[modifyStart];
				mergeCount += 2;
			}
			mergeStyles[mergeCount >> 1] = newStyles[i >> 1];
			mergeRanges[mergeCount] = newStart;
			mergeRanges[mergeCount + 1] = newRanges[i + 1];
			mergeCount += 2;
			if (modifyEnd < rangeCount && ranges[modifyEnd] < newEnd && newEnd < ranges[modifyEnd] + ranges[modifyEnd + 1]) {
				mergeStyles[mergeCount >> 1] = styles[modifyEnd >> 1];
				mergeRanges[mergeCount] = newEnd;
				mergeRanges[mergeCount + 1] = ranges[modifyEnd] + ranges[modifyEnd + 1] - newEnd;
				mergeCount += 2;
				modifyLast = 2;
			}
			int grow = addMerge(mergeRanges, mergeStyles, mergeCount, modifyStart, modifyEnd + modifyLast);
			rangeCount += grow;
			modifyStart = modifyEnd += grow;
		}
	} else {
		int start = newStyles[0].start;
		int modifyStart = getRangeIndex(start, -1, styleCount), modifyEnd;
		boolean insert = modifyStart == styleCount;
		if (!insert) {
			int end = newStyles[newStyles.length - 1].start + newStyles[newStyles.length - 1].length;
			modifyEnd = getRangeIndex(end, modifyStart - 1, styleCount);
			insert = modifyStart == modifyEnd && styles[modifyStart].start >= end;
		}
		if (insert) {
			addMerge(newStyles, newStyles.length, modifyStart, modifyStart);
			return;
		}
		modifyEnd = modifyStart;
		StyleRange[] mergeStyles = new StyleRange[3];
		for (StyleRange newStyle : newStyles) {
			StyleRange style;
			int newStart = newStyle.start;
			int newEnd = newStart + newStyle.length;
			if (newStart == newEnd) continue;
			int modifyLast = 0, mergeCount = 0;
			while (modifyEnd < styleCount) {
				if (newStart >= styles[modifyStart].start + styles[modifyStart].length) modifyStart++;
				if (styles[modifyEnd].start + styles[modifyEnd].length > newEnd) break;
				modifyEnd++;
			}
			style = styles[modifyStart];
			if (style.start < newStart && newStart < style.start + style.length) {
				style = mergeStyles[mergeCount++] = (StyleRange)style.clone();
				style.length = newStart - style.start;
			}
			mergeStyles[mergeCount++] = newStyle;
			if (modifyEnd < styleCount) {
				style = styles[modifyEnd];
				if (style.start < newEnd && newEnd < style.start + style.length) {
					style = mergeStyles[mergeCount++] = (StyleRange)style.clone();
					style.length += style.start - newEnd;
					style.start = newEnd;
					modifyLast = 1;
				}
			}
			int grow = addMerge(mergeStyles, mergeCount, modifyStart, modifyEnd + modifyLast);
			modifyStart = modifyEnd += grow;
		}
	}
}
void textChanging(TextChangingEvent event) {
	int start = event.start;
	int newCharCount = event.newCharCount, replaceCharCount = event.replaceCharCount;
	int newLineCount = event.newLineCount, replaceLineCount = event.replaceLineCount;

	updateRanges(start, replaceCharCount, newCharCount);

	int startLine = content.getLineAtOffset(start);
	if (replaceCharCount == content.getCharCount()) lines = null;
	if (replaceLineCount == lineCount) {
		lineCount = newLineCount;
		lineSizes = new LineSizeInfo[lineCount];
		reset(0, lineCount);
	} else {
		int startIndex = startLine + replaceLineCount + 1;
		int endIndex = startLine + newLineCount + 1;
		if(lineCount < startLine) {
			SWT.error(SWT.ERROR_INVALID_RANGE, null, "bug 478020: lineCount < startLine: " + lineCount + ":" + startLine);
		}
		if(lineCount < startIndex) {
			SWT.error(SWT.ERROR_INVALID_RANGE, null, "bug 478020: lineCount < startIndex: " + lineCount + ":" + startIndex);
		}
		int delta = newLineCount - replaceLineCount;
		if (lineCount + delta > lineSizes.length) {
			LineSizeInfo[] newLineSizes = new LineSizeInfo[lineCount + delta + GROW];
			System.arraycopy(lineSizes, 0, newLineSizes, 0, lineCount);
			lineSizes = newLineSizes;
		}
		if (lines != null) {
			if (lineCount + delta > lines.length) {
				LineInfo[] newLines = new LineInfo[lineCount + delta + GROW];
				System.arraycopy(lines, 0, newLines, 0, lineCount);
				lines = newLines;
			}
		}
		System.arraycopy(lineSizes, startIndex, lineSizes, endIndex, lineCount - startIndex);
		for (int i = startLine; i < endIndex; i++) {
			lineSizes[i] = null;
		}
		for (int i = lineCount + delta; i < lineCount; i++) {
			lineSizes[i] = null;
		}
		if (layouts != null) {
			int layoutStartLine = startLine - topIndex;
			int layoutEndLine = layoutStartLine + replaceLineCount + 1;
			for (int i = layoutStartLine; i < layoutEndLine; i++) {
				if (0 <= i && i < layouts.length) {
					if (layouts[i] != null) layouts[i].dispose();
					layouts[i] = null;
					if (bullets != null && bulletsIndices != null) bullets[i] = null;
				}
			}
			if (delta > 0) {
				for (int i = layouts.length - 1; i >= layoutEndLine; i--) {
					if (0 <= i && i < layouts.length) {
						endIndex = i + delta;
						if (0 <= endIndex && endIndex < layouts.length) {
							layouts[endIndex] = layouts[i];
							layouts[i] = null;
							if (bullets != null && bulletsIndices != null) {
								bullets[endIndex] = bullets[i];
								bulletsIndices[endIndex] = bulletsIndices[i];
								bullets[i] = null;
							}
						} else {
							if (layouts[i] != null) layouts[i].dispose();
							layouts[i] = null;
							if (bullets != null && bulletsIndices != null) bullets[i] = null;
						}
					}
				}
			} else if (delta < 0) {
				for (int i = layoutEndLine; i < layouts.length; i++) {
					if (0 <= i && i < layouts.length) {
						endIndex = i + delta;
						if (0 <= endIndex && endIndex < layouts.length) {
							layouts[endIndex] = layouts[i];
							layouts[i] = null;
							if (bullets != null && bulletsIndices != null) {
								bullets[endIndex] = bullets[i];
								bulletsIndices[endIndex] = bulletsIndices[i];
								bullets[i] = null;
							}
						} else {
							if (layouts[i] != null) layouts[i].dispose();
							layouts[i] = null;
							if (bullets != null && bulletsIndices != null) bullets[i] = null;
						}
					}
				}
			}
		}
		if (replaceLineCount != 0 || newLineCount != 0) {
			int startLineOffset = content.getOffsetAtLine(startLine);
			if (startLineOffset != start) startLine++;
			updateBullets(startLine, replaceLineCount, newLineCount, true);
			if (lines != null) {
				startIndex = startLine + replaceLineCount;
				endIndex = startLine + newLineCount;
				System.arraycopy(lines, startIndex, lines, endIndex, lineCount - startIndex);
				for (int i = startLine; i < endIndex; i++) {
					lines[i] = null;
				}
				for (int i = lineCount + delta; i < lineCount; i++) {
					lines[i] = null;
				}
			}
		}
		lineCount += delta;
		if (maxWidthLineIndex != -1 && startLine <= maxWidthLineIndex && maxWidthLineIndex <= startLine + replaceLineCount) {
			maxWidth = 0;
			maxWidthLineIndex = -1;
			for (int i = 0; i < lineCount; i++) {
				LineSizeInfo lineSize = getLineSize(i);
				if (lineSize.width > maxWidth) {
					maxWidth = lineSize.width;
					maxWidthLineIndex = i;
				}
			}
		}
	}
}
void updateBullets(int startLine, int replaceLineCount, int newLineCount, boolean update) {
	if (bullets == null) return;
	if (bulletsIndices != null) return;
	for (Bullet bullet : bullets) {
		int[] lines = bullet.removeIndices(startLine, replaceLineCount, newLineCount, update);
		if (lines != null) {
			if (redrawLines == null) {
				redrawLines = lines;
			} else {
				int[] newRedrawBullets = new int[redrawLines.length + lines.length];
				System.arraycopy(redrawLines, 0, newRedrawBullets, 0, redrawLines.length);
				System.arraycopy(lines, 0, newRedrawBullets, redrawLines.length, lines.length);
				redrawLines = newRedrawBullets;
			}
		}
	}
	int removed = 0;
	for (Bullet bullet : bullets) {
		if (bullet.size() == 0) removed++;
	}
	if (removed > 0) {
		if (removed == bullets.length) {
			bullets = null;
		} else {
			Bullet[] newBulletsList = new Bullet[bullets.length - removed];
			for (int i = 0, j = 0; i < bullets.length; i++) {
				Bullet bullet = bullets[i];
				if (bullet.size() > 0) newBulletsList[j++] = bullet;
			}
			bullets = newBulletsList;
		}
	}
}
void updateRanges(int start, int replaceCharCount, int newCharCount) {
	if (styleCount == 0 || (replaceCharCount == 0 && newCharCount == 0)) return;
	if (ranges != null) {
		int rangeCount = styleCount << 1;
		int modifyStart = getRangeIndex(start, -1, rangeCount);
		if (modifyStart == rangeCount) return;
		int end = start + replaceCharCount;
		int modifyEnd = getRangeIndex(end, modifyStart - 1, rangeCount);
		int offset = newCharCount - replaceCharCount;
		if (modifyStart == modifyEnd && ranges[modifyStart] < start && end < ranges[modifyEnd] + ranges[modifyEnd + 1]) {
			if (newCharCount == 0) {
				ranges[modifyStart + 1] -= replaceCharCount;
				modifyEnd += 2;
			} else {
				if (rangeCount + 2 > ranges.length) {
					int[] newRanges = new int[ranges.length + (GROW << 1)];
					System.arraycopy(ranges, 0, newRanges, 0, rangeCount);
					ranges = newRanges;
					StyleRange[] newStyles = new StyleRange[styles.length + GROW];
					System.arraycopy(styles, 0, newStyles, 0, styleCount);
					styles = newStyles;
				}
				System.arraycopy(ranges, modifyStart + 2, ranges, modifyStart + 4, rangeCount - (modifyStart + 2));
				System.arraycopy(styles, (modifyStart + 2) >> 1, styles, (modifyStart + 4) >> 1, styleCount - ((modifyStart + 2) >> 1));
				ranges[modifyStart + 3] = ranges[modifyStart] + ranges[modifyStart + 1] - end;
				ranges[modifyStart + 2] = start + newCharCount;
				ranges[modifyStart + 1] = start - ranges[modifyStart];
				styles[(modifyStart >> 1) + 1] = styles[modifyStart >> 1];
				rangeCount += 2;
				styleCount++;
				modifyEnd += 4;
			}
			if (offset != 0) {
				for (int i = modifyEnd; i < rangeCount; i += 2) {
					ranges[i] += offset;
				}
			}
		} else {
			if (ranges[modifyStart] < start && start < ranges[modifyStart] + ranges[modifyStart + 1]) {
				ranges[modifyStart + 1] = start - ranges[modifyStart];
				modifyStart += 2;
			}
			if (modifyEnd < rangeCount && ranges[modifyEnd] < end && end < ranges[modifyEnd] + ranges[modifyEnd + 1]) {
				ranges[modifyEnd + 1] = ranges[modifyEnd] + ranges[modifyEnd + 1] - end;
				ranges[modifyEnd] = end;
			}
			if (offset != 0) {
				for (int i = modifyEnd; i < rangeCount; i += 2) {
					ranges[i] += offset;
				}
			}
			System.arraycopy(ranges, modifyEnd, ranges, modifyStart, rangeCount - modifyEnd);
			System.arraycopy(styles, modifyEnd >> 1, styles, modifyStart >> 1, styleCount - (modifyEnd >> 1));
			styleCount -= (modifyEnd - modifyStart) >> 1;
		}
	} else {
		int modifyStart = getRangeIndex(start, -1, styleCount);
		if (modifyStart == styleCount) return;
		int end = start + replaceCharCount;
		int modifyEnd = getRangeIndex(end, modifyStart - 1, styleCount);
		int offset = newCharCount - replaceCharCount;
		if (modifyStart == modifyEnd && styles[modifyStart].start < start && end < styles[modifyEnd].start + styles[modifyEnd].length) {
			if (newCharCount == 0) {
				styles[modifyStart].length -= replaceCharCount;
				modifyEnd++;
			} else {
				if (styleCount + 1 > styles.length) {
					StyleRange[] newStyles = new StyleRange[styles.length + GROW];
					System.arraycopy(styles, 0, newStyles, 0, styleCount);
					styles = newStyles;
				}
				System.arraycopy(styles, modifyStart + 1, styles, modifyStart + 2, styleCount - (modifyStart + 1));
				styles[modifyStart + 1] = (StyleRange)styles[modifyStart].clone();
				styles[modifyStart + 1].length = styles[modifyStart].start + styles[modifyStart].length - end;
				styles[modifyStart + 1].start = start + newCharCount;
				styles[modifyStart].length = start - styles[modifyStart].start;
				styleCount++;
				modifyEnd += 2;
			}
			if (offset != 0) {
				for (int i = modifyEnd; i < styleCount; i++) {
					styles[i].start += offset;
				}
			}
		} else {
			if (styles[modifyStart].start < start && start < styles[modifyStart].start + styles[modifyStart].length) {
				styles[modifyStart].length = start - styles[modifyStart].start;
				modifyStart++;
			}
			if (modifyEnd < styleCount && styles[modifyEnd].start < end && end < styles[modifyEnd].start + styles[modifyEnd].length) {
				styles[modifyEnd].length = styles[modifyEnd].start + styles[modifyEnd].length - end;
				styles[modifyEnd].start = end;
			}
			if (offset != 0) {
				for (int i = modifyEnd; i < styleCount; i++) {
					styles[i].start += offset;
				}
			}
			System.arraycopy(styles, modifyEnd, styles, modifyStart, styleCount - modifyEnd);
			styleCount -= modifyEnd - modifyStart;
		}
	}
}

public boolean hasVerticalIndent() {
	return Arrays.stream(lines).filter(Objects::nonNull) //
			.mapToInt(line -> line.verticalIndent) //
			.anyMatch(n -> n != 0);
}


}
