From dbff74c70654f881d6234ffe67857da0231a1be6 Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Mon, 8 Jul 2024 18:24:05 +0200 Subject: [PATCH] selection background drawn with the line spacing for multiline selection --- .../org/eclipse/swt/graphics/TextLayout.java | 7 +++++-- .../org/eclipse/swt/graphics/TextLayout.java | 18 ++++++++++++++---- .../org/eclipse/swt/graphics/TextLayout.java | 16 ++++++++++------ 3 files changed, 29 insertions(+), 12 deletions(-) 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 d4eb922aeaa..9930d987d79 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 @@ -498,6 +498,9 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo rect.y += pt.y; if (fixedLineMetrics != null) rect.height = fixedLineMetrics.height; rect.height = Math.max(rect.height, ascent + descent); + if ((flags & (SWT.FULL_SELECTION | SWT.DELIMITER_SELECTION)) != 0 && (/*hasSelection ||*/ (flags & SWT.LAST_LINE_SELECTION) != 0)) { + rect.height += spacing; + } path.appendBezierPathWithRect(rect); } } @@ -506,8 +509,8 @@ public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Colo NSRect bounds = lineBounds[lineBounds.length - 1]; rect.x = pt.x + bounds.x + bounds.width; rect.y = y + bounds.y; - rect.width = (flags & SWT.FULL_SELECTION) != 0 ? 0x7fffffff : bounds.height / 3; - rect.height = Math.max(bounds.height, ascent + descent); + rect.width = (flags & SWT.FULL_SELECTION) != 0 ? 0x7fffffff : (bounds.height + spacing) / 3; + rect.height = Math.max(bounds.height + spacing, ascent + descent); path.appendBezierPathWithRect(rect); } selectionColor.setFill(); 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 a0eb06dee5e..f7a8cbf6f5b 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 @@ -644,6 +644,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; GCData data = gc.data; long cairo = data.cairo; + boolean extent = false; if ((flags & (SWT.FULL_SELECTION | SWT.DELIMITER_SELECTION)) != 0 && (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0)) { long [] attrs = new long [1]; int[] nAttrs = new int[1]; @@ -666,7 +667,6 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col } else { lineEnd = (int)OS.g_utf16_strlen(ptr, -1); } - boolean extent = false; if (lineIndex == lineCount - 1 && (flags & SWT.LAST_LINE_SELECTION) != 0) { extent = true; } else { @@ -687,6 +687,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col if (ascentInPoints != -1 && descentInPoints != -1) { height = Math.max (height, DPIUtil.autoScaleUp(getDevice(), ascentInPoints + descentInPoints)); } + height += getSpacingInPixels(); int width = (flags & SWT.FULL_SELECTION) != 0 ? 0x7fff : height / 3; Cairo.cairo_rectangle(cairo, lineX, lineY, width, height); Cairo.cairo_fill(cairo); @@ -717,6 +718,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col selectionEnd = translateOffset(selectionEnd); if (selectionForeground == null) selectionForeground = device.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); if (selectionBackground == null) selectionBackground = device.getSystemColor(SWT.COLOR_LIST_SELECTION); + int yExtent = extent ? getSpacingInPixels() : 0; boolean fullSelection = selectionStart == 0 && selectionEnd == length - 1; if (fullSelection) { long ptr = OS.pango_layout_get_text(layout); @@ -725,7 +727,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col Cairo.cairo_scale(cairo, -1, 1); Cairo.cairo_translate(cairo, -2 * x - width(), 0); } - drawWithCairo(gc, x, y, 0, C.strlen(ptr), fullSelection, selectionForeground.handle, + drawWithCairo(gc, x, y, 0, C.strlen(ptr), yExtent, fullSelection, selectionForeground.handle, selectionBackground.handle); if ((data.style & SWT.MIRRORED) != 0) { Cairo.cairo_restore(cairo); @@ -742,7 +744,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col Cairo.cairo_scale(cairo, -1, 1); Cairo.cairo_translate(cairo, -2 * x - width(), 0); } - drawWithCairo(gc, x, y, byteSelStart, byteSelEnd, fullSelection, selectionForeground.handle, + drawWithCairo(gc, x, y, byteSelStart, byteSelEnd, yExtent, fullSelection, selectionForeground.handle, selectionBackground.handle); if ((data.style & SWT.MIRRORED) != 0) { Cairo.cairo_restore(cairo); @@ -752,7 +754,7 @@ void drawInPixels(GC gc, int x, int y, int selectionStart, int selectionEnd, Col Cairo.cairo_new_path(cairo); } -void drawWithCairo(GC gc, int x, int y, int start, int end, boolean fullSelection, GdkRGBA fg, GdkRGBA bg) { +void drawWithCairo(GC gc, int x, int y, int start, int end, int yExtent, boolean fullSelection, GdkRGBA fg, GdkRGBA bg) { GCData data = gc.data; long cairo = data.cairo; Cairo.cairo_save(cairo); @@ -763,6 +765,14 @@ void drawWithCairo(GC gc, int x, int y, int start, int end, boolean fullSelectio int[] ranges = new int[]{start, end}; long rgn = metricsAdapter.gdk_pango_layout_get_clip_region(layout, x, y, ranges, ranges.length / 2); if (rgn != 0) { + if (yExtent > 0) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t(); + Cairo.cairo_region_get_extents(rgn, rect); + rect.height += yExtent; + long extendRgn = Cairo.cairo_region_create_rectangle(rect); + Cairo.cairo_region_union(rgn, extendRgn); + Cairo.cairo_region_destroy(extendRgn); + } GDK.gdk_cairo_region(cairo, rgn); Cairo.cairo_clip(cairo); Cairo.cairo_set_source_rgba(cairo, bg.red, bg.green, bg.blue, bg.alpha); 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 e09684600af..4ec71e5988b 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 @@ -842,10 +842,10 @@ void drawInPixels (GC gc, int x, int y, int selectionStart, int selectionEnd, Co int drawY = y + DPIUtil.scaleUp(getDevice(), lineY[line], getZoom(gc)); StyleItem[] lineRuns = runs[line]; int lineHeight = DPIUtil.scaleUp(getDevice(), lineY[line+1] - lineY[line] - lineSpacingInPoints, getZoom(gc)); - + int lineHeightWithSpacing = DPIUtil.scaleUp(getDevice(), lineY[line+1] - lineY[line], getZoom(gc)); //Draw last line selection + boolean extents = false; if ((flags & (SWT.FULL_SELECTION | SWT.DELIMITER_SELECTION)) != 0 && (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0)) { - boolean extents = false; if (line == runs.length - 1 && (flags & SWT.LAST_LINE_SELECTION) != 0) { extents = true; } else { @@ -864,13 +864,13 @@ void drawInPixels (GC gc, int x, int y, int selectionStart, int selectionEnd, Co if ((flags & SWT.FULL_SELECTION) != 0) { width = 0x6FFFFFF; } else { - width = lineHeight / 3; + width = lineHeightWithSpacing / 3; } if (gdip) { - Gdip.Graphics_FillRectangle(gdipGraphics, gdipSelBackground, drawX + lineWidthInPixels[line], drawY, width, lineHeight); + Gdip.Graphics_FillRectangle(gdipGraphics, gdipSelBackground, drawX + lineWidthInPixels[line], drawY, width, lineHeightWithSpacing); } else { OS.SelectObject(hdc, selBackground); - OS.PatBlt(hdc, drawX + lineWidthInPixels[line], drawY, width, lineHeight, OS.PATCOPY); + OS.PatBlt(hdc, drawX + lineWidthInPixels[line], drawY, width, lineHeightWithSpacing, OS.PATCOPY); } } } @@ -884,7 +884,11 @@ void drawInPixels (GC gc, int x, int y, int selectionStart, int selectionEnd, Co if (drawX > clip.x + clip.width) break; if (drawX + run.width >= clip.x) { if (!run.lineBreak || run.softBreak) { - OS.SetRect(rect, drawX, drawY, drawX + run.width, drawY + lineHeight); + if (extents) { + OS.SetRect(rect, drawX, drawY, drawX + run.width, drawY + lineHeightWithSpacing); + }else { + OS.SetRect(rect, drawX, drawY, drawX + run.width, drawY + lineHeight); + } if (gdip) { drawRunBackgroundGDIP(run, gdipGraphics, rect, selectionStart, selectionEnd, alpha, gdipSelBackground, hasSelection); } else {