diff options
author | angelozerr | 2018-09-28 12:51:23 +0000 |
---|---|---|
committer | Lakshmi Shanmugam | 2018-11-16 17:16:26 +0000 |
commit | ed8f052b607fe5aa79824f0541c4d7cf43fd6d3a (patch) | |
tree | 0c758b496bf1291279fb3aa9b7387ca597c247a9 | |
parent | 6b4d3fd2e1fbcd73bb9b14d15c9ab092e55ddfaa (diff) | |
download | eclipse.platform.swt-ed8f052b607fe5aa79824f0541c4d7cf43fd6d3a.tar.gz eclipse.platform.swt-ed8f052b607fe5aa79824f0541c4d7cf43fd6d3a.tar.xz eclipse.platform.swt-ed8f052b607fe5aa79824f0541c4d7cf43fd6d3a.zip |
Bug 539618 - [StyledText] Allow to define a top margin for a given line
or range
Change-Id: Ia3febd7de810c8fed7b75794d43c6e120523c87d
Signed-off-by: angelozerr <angelo.zerr@gmail.com>
9 files changed, 334 insertions, 16 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/LineStyleEvent.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/LineStyleEvent.java index 41c830b582..100e42f59c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/LineStyleEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/LineStyleEvent.java @@ -65,6 +65,13 @@ public class LineStyleEvent extends TypedEvent { public int indent; /** + * line vertical indent (input, output) + * + * @since 3.108 + */ + public int verticalIndent; + + /** * line wrap indent (input, output) * * @since 3.6 @@ -114,6 +121,7 @@ public LineStyleEvent(StyledTextEvent e) { alignment = e.alignment; justify = e.justify; indent = e.indent; + verticalIndent = e.verticalIndent; wrapIndent = e.wrapIndent; bullet = e.bullet; bulletIndex = e.bulletIndex; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java index 050b6c27af..a3f5d7e7bf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java @@ -4150,6 +4150,30 @@ public int getLineIndent(int index) { return isListening(ST.LineGetStyle) ? 0 : renderer.getLineIndent(index, indent); } /** + * Returns the vertical indentation of the line at the given index. + * + * @param index the index of the line + * + * @return the line vertical indentation + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT when the index is invalid</li> + * </ul> + * + * @since 3.108 + */ +public int getLineVerticalIndent(int index) { + checkWidget(); + if (index < 0 || index >= content.getLineCount()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return isListening(ST.LineGetStyle) ? 0 : renderer.getLineVerticalIndent(index); +} +/** * Returns whether the line at the given index is justified. * * @param index the index of the line @@ -5544,7 +5568,7 @@ Point getPointAtOffset(int offset) { } } } else { - point = new Point(layout.getIndent(), 0); + point = new Point(layout.getIndent(), layout.getVerticalIndent()); } renderer.disposeTextLayout(layout); point.x += leftMargin - horizontalScrollOffset; @@ -9314,6 +9338,62 @@ public void setLineIndent(int startLine, int lineCount, int indent) { setCaretLocation(); } } + +/** + * Sets the vertical indent of the specified lines. + * <p> + * Should not be called if a LineStyleListener has been set since the listener + * maintains the line attributes. + * </p><p> + * All line attributes are maintained relative to the line text, not the + * line index that is specified in this method call. + * During text changes, when entire lines are inserted or removed, the line + * attributes that are associated with the lines after the change + * will "move" with their respective text. An entire line is defined as + * extending from the first character on a line to the last and including the + * line delimiter. + * </p><p> + * When two lines are joined by deleting a line delimiter, the top line + * attributes take precedence and the attributes of the bottom line are deleted. + * For all other text changes line attributes will remain unchanged. + * </p><p> + * Setting both line spacing and vertical indent on a line would result in the + * spacing and indent add up for the line. + * </p> + * + * @param lineIndex line index the vertical indent is applied to, 0 based + * @param verticalLineIndent vertical line indent + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT when the specified line index is invalid</li> + * </ul> + * @since 3.108 + */ +public void setLineVerticalIndent(int lineIndex, int verticalLineIndent) { + checkWidget(); + if (isListening(ST.LineGetStyle)) return; + if (lineIndex < 0 || lineIndex >= content.getLineCount()) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (verticalLineIndent == renderer.getLineVerticalIndent(lineIndex)) { + return; + } + setVariableLineHeight(); + int oldBottom = getLinePixel(lineIndex + 1); + renderer.setLineVerticalIndent(lineIndex, verticalLineIndent); + resetCache(lineIndex, 1); + int newBottom = getLinePixel(lineIndex + 1); + redrawLines(lineIndex, 1, oldBottom != newBottom); + int caretLine = getCaretLine(); + if (lineIndex <= caretLine && caretLine < lineIndex + 1) { + setCaretLocation(); + } +} + /** * Sets the justify of the specified lines. * <p> diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextEvent.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextEvent.java index c2f161adba..7004d371e3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextEvent.java @@ -25,6 +25,7 @@ class StyledTextEvent extends Event { StyleRange[] styles; int alignment; int indent; + int verticalIndent; int wrapIndent; boolean justify; Bullet bullet; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java index bb580b3ab6..d27682f46e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextListener.java @@ -14,8 +14,8 @@ package org.eclipse.swt.custom; import org.eclipse.swt.events.*; +import org.eclipse.swt.internal.*; import org.eclipse.swt.widgets.*; -import org.eclipse.swt.internal.SWTEventListener; class StyledTextListener extends TypedListener { /** @@ -54,6 +54,7 @@ public void handleEvent(Event e) { ((StyledTextEvent) e).styles = lineStyleEvent.styles; ((StyledTextEvent) e).alignment = lineStyleEvent.alignment; ((StyledTextEvent) e).indent = lineStyleEvent.indent; + ((StyledTextEvent) e).verticalIndent = lineStyleEvent.verticalIndent; ((StyledTextEvent) e).wrapIndent = lineStyleEvent.wrapIndent; ((StyledTextEvent) e).justify = lineStyleEvent.justify; ((StyledTextEvent) e).bullet = lineStyleEvent.bullet; diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java index 75153c957a..776d6ff069 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextRenderer.java @@ -81,6 +81,7 @@ class StyledTextRenderer { 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 { @@ -157,6 +158,7 @@ class StyledTextRenderer { int[] segments; char[] segmentsChars; int[] tabStops; + int verticalIndent; public LineInfo() { } @@ -171,6 +173,7 @@ class StyledTextRenderer { segments = info.segments; segmentsChars = info.segmentsChars; tabStops = info.tabStops; + verticalIndent = info.verticalIndent; } } } @@ -370,7 +373,7 @@ void clearLineStyle(int startLine, int count) { for (int i = startLine; i < startLine + count; i++) { LineInfo info = lines[i]; if (info != null) { - info.flags &= ~(ALIGNMENT | INDENT | WRAP_INDENT | JUSTIFY | TABSTOPS); + info.flags &= ~(ALIGNMENT | INDENT | VERTICAL_INDENT | WRAP_INDENT | JUSTIFY | TABSTOPS); if (info.flags == 0) lines[i] = null; } } @@ -458,9 +461,14 @@ int drawLine(int lineIndex, int paintX, int paintY, GC gc, Color widgetBackgroun 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, client.width, height); + gc.fillRectangle(client.x, paintY + verticalIndent, client.width, height - verticalIndent); } else { gc.setBackground(widgetBackground); styledText.drawBackground(gc, client.x, paintY, client.width, height); @@ -725,6 +733,14 @@ int getLineIndent(int index, int defaultIndent) { } 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]; @@ -976,6 +992,7 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac char[] segmentChars = null; int indent = 0; int wrapIndent = 0; + int verticalIndent = 0; int alignment = SWT.LEFT; int textDirection = orientation; boolean justify = false; @@ -1005,6 +1022,7 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac } if (event != null) { indent = event.indent; + verticalIndent = event.verticalIndent; wrapIndent = event.wrapIndent; alignment = event.alignment; justify = event.justify; @@ -1039,6 +1057,7 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac 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; @@ -1085,6 +1104,7 @@ TextLayout getTextLayout(int lineIndex, int orientation, int width, int lineSpac layout.setTabs(tabs); layout.setDefaultTabWidth(tabLength); layout.setIndent(indent); + layout.setVerticalIndent(verticalIndent); layout.setWrapIndent(wrapIndent); layout.setAlignment(alignment); layout.setJustify(justify); @@ -1392,6 +1412,15 @@ void setLineIndent(int startLine, int count, int 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++) { @@ -1851,4 +1880,6 @@ void updateRanges(int start, int replaceCharCount, int newCharCount) { } } } + + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java index 7ebdf0da5e..c12628e54e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java @@ -45,7 +45,7 @@ public final class TextLayout extends Resource { String text; StyleItem[] styles; int stylesCount; - int spacing, ascent, descent, indent, wrapIndent; + int spacing, ascent, descent, indent, wrapIndent, verticalIndentInPoints; boolean justify; int alignment; int[] tabs; @@ -455,6 +455,7 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo computeRuns(); int length = translateOffset(text.length()); if (length == 0 && flags == 0) return; + y += getVerticalIndent(); gc.handle.saveGraphicsState(); NSPoint pt = new NSPoint(); pt.x = x; @@ -753,7 +754,7 @@ public Rectangle getBounds() { rect.height = layoutManager.defaultLineHeightForFont(nsFont); } rect.height = Math.max(rect.height, ascent + descent) + spacing; - return new Rectangle(0, 0, (int)Math.ceil(rect.width), (int)Math.ceil(rect.height)); + return new Rectangle(0, 0, (int)Math.ceil(rect.width), (int)Math.ceil(rect.height) + getVerticalIndent()); } finally { if (pool != null) pool.release(); } @@ -802,7 +803,7 @@ public Rectangle getBounds(int start, int end) { top = Math.min(top, (int)rect.y); bottom = Math.max(bottom, (int)Math.ceil(rect.y + rect.height)); } - return new Rectangle(left, top, right - left, bottom - top); + return new Rectangle(left, top, right - left, bottom - top + getVerticalIndent()); } finally { if (pool != null) pool.release(); } @@ -1110,7 +1111,7 @@ public Point getLocation(int offset, boolean trailing) { point.x += bounds.width; } } - return new Point((int)point.x, (int)rect.y); + return new Point((int)point.x, (int)rect.y + getVerticalIndent()); } } finally { if (pool != null) pool.release(); @@ -1278,7 +1279,7 @@ public int getOffset(int x, int y, int[] trailing) { if (length == 0) return 0; NSPoint pt = new NSPoint(); pt.x = x; - pt.y = y; + pt.y = y - getVerticalIndent(); double /*float*/[] partialFraction = new double /*float*/[1]; long /*int*/ glyphIndex = layoutManager.glyphIndexForPoint(pt, textContainer, partialFraction); long /*int*/ charOffset = layoutManager.characterIndexForGlyphAtIndex(glyphIndex); @@ -1458,6 +1459,21 @@ public int getSpacing () { } /** + * Returns the vertical indent of the receiver. + * + * @return the vertical indent + * + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public int getVerticalIndent () { + checkLayout(); + return verticalIndentInPoints; +} + +/** * Gets the style of the receiver at the specified character offset. * * @param offset the text offset @@ -1991,6 +2007,34 @@ public void setSpacing (int spacing) { } /** + * Sets the vertical indent of the receiver. The vertical indent + * is the space left before the first line. + * + * @param verticalIndent the new vertical indent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the vertical indent is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public void setVerticalIndent (int verticalIndent) { + checkLayout(); + if (verticalIndent < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (this.verticalIndentInPoints == verticalIndent) return; + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + freeRuns(); + this.verticalIndentInPoints = verticalIndent; + } finally { + if (pool != null) pool.release(); + } +} + +/** * Sets the style of the receiver for the specified range. Styles previously * set for that range will be overwritten. The start and end offsets are * inclusive and will be clamped if out of range. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java index 82685e846d..fc462f0939 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java @@ -62,6 +62,7 @@ public final class TextLayout extends Resource { int stylesCount; long /*int*/ layout, context, attrList, selAttrList; int[] invalidOffsets; + int verticalIndentInPoints; static final char LTR_MARK = '\u200E', RTL_MARK = '\u200F', ZWS = '\u200B', ZWNBS = '\uFEFF'; /** @@ -465,6 +466,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col gc.checkGC(GC.FOREGROUND); int length = text.length(); x += Math.min (indent, wrapIndent); + y += getScaledVerticalIndent(); boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; GCData data = gc.data; long /*int*/ cairo = data.cairo; @@ -739,7 +741,7 @@ public Rectangle getBounds() { checkLayout(); Rectangle bounds = DPIUtil.autoScaleDown(getDevice(), getBoundsInPixels()); int lineCount = OS.pango_layout_get_line_count(layout); - int totalLineheight = 0; + int totalLineheight = getScaledVerticalIndent(); for (int i = 0; i < lineCount; i++) { totalLineheight += this.getLineBounds(i).height + OS.PANGO_PIXELS(OS.pango_layout_get_spacing(layout)); } @@ -759,7 +761,7 @@ Rectangle getBoundsInPixels() { height = Math.max (height, DPIUtil.autoScaleUp(getDevice(), ascentInPoints + descentInPoints)); } height += OS.PANGO_PIXELS(OS.pango_layout_get_spacing(layout)); - return new Rectangle(0, 0, width, height); + return new Rectangle(0, 0, width, height + getScaledVerticalIndent()); } /** @@ -834,7 +836,7 @@ Rectangle getBoundsInPixels(int start, int end) { Cairo.cairo_region_get_extents(clipRegion, rect); Cairo.cairo_region_destroy(clipRegion); rect.x += Math.min (indent, wrapIndent); - return new Rectangle(rect.x, rect.y, rect.width, rect.height); + return new Rectangle(rect.x, rect.y, rect.width, rect.height + getScaledVerticalIndent()); } /** @@ -1151,7 +1153,7 @@ Point getLocationInPixels(int offset, boolean trailing) { x = width() - x; } x += Math.min (indent, wrapIndent); - return new Point(x, OS.PANGO_PIXELS(y)); + return new Point(x, OS.PANGO_PIXELS(y) + getScaledVerticalIndent()); } /** @@ -1503,6 +1505,34 @@ int getSpacingInPixels () { } /** + * Returns the vertical indent of the receiver. + * + * @return the vertical indent + * + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public int getVerticalIndent () { + checkLayout(); + return verticalIndentInPoints; +} + +/** + * Returns the scaled vertical indent. + * + * @return the scaled vertical indent. + * @since 3.108 + */ +private int getScaledVerticalIndent() { + if (verticalIndentInPoints == 0) { + return verticalIndentInPoints; + } + return DPIUtil.autoScaleUp(getDevice(), verticalIndentInPoints); +} + +/** * Gets the style of the receiver at the specified character offset. * * @param offset the text offset @@ -1872,6 +1902,27 @@ void setSpacingInPixels (int spacing) { } /** + * Sets the vertical indent of the receiver. The vertical indent + * is the space left before the first line. + * + * @param verticalIndent the new vertical indent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the vertical indent is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public void setVerticalIndent (int verticalIndent) { + checkLayout(); + if (verticalIndent < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (this.verticalIndentInPoints == verticalIndent) return; + this.verticalIndentInPoints = verticalIndent; +} + +/** * Sets the offsets of the receiver's text segments. Text segments are used to * override the default behavior of the bidirectional algorithm. * Bidirectional reordering can happen within a text segment but not diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java index e3c730ca8f..10cee0d654 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java @@ -61,6 +61,7 @@ public final class TextLayout extends Resource { StyleItem[][] runs; int[] lineOffset, lineY, lineWidth; long /*int*/ mLangFontLink2; + int verticalIndentInPoints; static final char LTR_MARK = '\u200E', RTL_MARK = '\u200F'; static final int SCRIPT_VISATTR_SIZEOF = 2; @@ -181,6 +182,7 @@ public TextLayout (Device device) { super(device); wrapWidth = ascentInPixels = descentInPixels = -1; lineSpacingInPoints = 0; + verticalIndentInPoints = 0; orientation = SWT.LEFT_TO_RIGHT; textDirection = SWT.LEFT_TO_RIGHT; styles = new StyleItem[2]; @@ -648,6 +650,7 @@ void drawInPixels (GC gc, int x, int y, int selectionStart, int selectionEnd, Co if (selectionBackground != null && selectionBackground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); int length = text.length(); if (length == 0 && flags == 0) return; + y += getScaledVerticalIndent(); long /*int*/ hdc = gc.handle; Rectangle clip = gc.getClippingInPixels(); GCData data = gc.data; @@ -1640,7 +1643,7 @@ public Rectangle getBounds () { width = Math.max(width, lineWidth[line] + getLineIndent(line)); } } - return new Rectangle (0, 0, DPIUtil.autoScaleDown(getDevice(), width), lineY[lineY.length - 1]); + return new Rectangle (0, 0, DPIUtil.autoScaleDown(getDevice(), width), lineY[lineY.length - 1] + getScaledVerticalIndent()); } /** @@ -1744,7 +1747,7 @@ Rectangle getBoundsInPixels (int start, int end) { top = Math.min(top, DPIUtil.autoScaleUp(getDevice(), lineY[lineIndex])); bottom = Math.max(bottom, DPIUtil.autoScaleUp(getDevice(), lineY[lineIndex + 1] - lineSpacingInPoints)); } - return new Rectangle(left, top, right - left, bottom - top); + return new Rectangle(left, top, right - left, bottom - top + getScaledVerticalIndent()); } /** @@ -2107,7 +2110,7 @@ Point getLocationInPixels (int offset, boolean trailing) { OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); width = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; } - return new Point(run.x + width, DPIUtil.autoScaleUp(getDevice(), lineY[line])); + return new Point(run.x + width, DPIUtil.autoScaleUp(getDevice(), lineY[line]) + getScaledVerticalIndent()); } } return new Point(0, 0); @@ -2519,6 +2522,34 @@ public int getSpacing () { } /** + * Returns the vertical indent of the receiver. + * + * @return the vertical indent + * + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public int getVerticalIndent () { + checkLayout(); + return verticalIndentInPoints; +} + +/** + * Returns the scaled vertical indent. + * + * @return the scaled vertical indent. + * @since 3.108 + */ +private int getScaledVerticalIndent() { + if (verticalIndentInPoints == 0) { + return verticalIndentInPoints; + } + return DPIUtil.autoScaleUp(getDevice(), verticalIndentInPoints); +} + +/** * Gets the style of the receiver at the specified character offset. * * @param offset the text offset @@ -3136,6 +3167,27 @@ public void setSpacing (int spacing) { } /** + * Sets the vertical indent of the receiver. The vertical indent + * is the space left before the first line. + * + * @param verticalIndent the new vertical indent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the vertical indent is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> + * </ul> + * @since 3.108 + */ +public void setVerticalIndent (int verticalIndent) { + checkLayout(); + if (verticalIndent < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (this.verticalIndentInPoints == verticalIndent) return; + this.verticalIndentInPoints = verticalIndent; +} + +/** * Sets the style of the receiver for the specified range. Styles previously * set for that range will be overwritten. The start and end offsets are * inclusive and will be clamped if out of range. diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet374.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet374.java new file mode 100644 index 0000000000..1a3081ff3c --- /dev/null +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet374.java @@ -0,0 +1,50 @@ +/**
+ * Copyright (c) 2018 Angelo ZERR.
+ * + * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [StyledText] Allow to define a top margin for a given line or range - Bug 539618
+ */
+package org.eclipse.swt.snippets;
+
+/*
+ * example snippet: customize line vertical indent
+ *
+ * For a list of all SWT example snippets see
+ * http://www.eclipse.org/swt/snippets/
+ *
+ * @since 3.108
+ */
+import org.eclipse.swt.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class Snippet374 {
+
+ public static void main(String[] args) throws Exception {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setLayout(new FillLayout());
+ shell.setText("Customize line vertical indent");
+
+ StyledText text = new StyledText(shell, SWT.BORDER | SWT.V_SCROLL);
+ text.setWordWrap(true);
+ text.setText("word1 word2 word3 word4");
+ text.setLineVerticalIndent(0, 20);
+
+ shell.pack();
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+}
|