From 30fd8efc3f07d9fe563e620620015a94d1966b44 Mon Sep 17 00:00:00 2001 From: Amartya Parijat Date: Wed, 9 Jul 2025 13:26:44 +0200 Subject: [PATCH] WIP --- .../org/eclipse/swt/custom/StyledText.java | 25 ++++++++++++++++++ .../swt/custom/StyledTextRenderer.java | 25 +++++++++++------- .../org/eclipse/swt/graphics/Point.java | 12 +++++++++ .../org/eclipse/swt/graphics/Rectangle.java | 26 +++++++++++++++++++ .../win32/org/eclipse/swt/graphics/GC.java | 7 +++++ .../org/eclipse/swt/graphics/TextLayout.java | 3 ++- .../win32/org/eclipse/swt/widgets/Canvas.java | 6 +++++ 7 files changed, 93 insertions(+), 11 deletions(-) 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 aa73e8ecd74..1de1f8ff100 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 @@ -3886,6 +3886,31 @@ public int getLinePixel(int lineIndex) { } return height + topMargin; } + +public float getLinePixelFloat(int lineIndex) { + checkWidget(); + int zoom = DPIUtil.getZoomForAutoscaleProperty(nativeZoom); + int lineCount = content.getLineCount(); + lineIndex = Math.max(0, Math.min(lineCount, lineIndex)); + if (isFixedLineHeight()) { + int lineHeight = renderer.getLineHeight(); + float lh = DPIUtil.scaleDown((float) DPIUtil.scaleUp(lineHeight, zoom), zoom); + return lineIndex * lh - getVerticalScrollOffset() + topMargin; + } + if (lineIndex == topIndex) + return topIndexY + topMargin; + int height = topIndexY; + if (lineIndex > topIndex) { + for (int i = topIndex; i < lineIndex; i++) { + height += DPIUtil.scaleDown((float) DPIUtil.scaleUp(renderer.getLineHeight(i), zoom), zoom); + } + } else { + for (int i = topIndex - 1; i >= lineIndex; i--) { + height -= DPIUtil.scaleDown((float) DPIUtil.scaleUp(renderer.getLineHeight(i), zoom), zoom); + } + } + return height + topMargin; +} /** * Returns the line index for a y, relative to the client area. * The line index returned is always in the range 0..lineCount - 1. 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 fa0281c2b31..e6b81e195be 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 @@ -184,7 +184,7 @@ public LineInfo(LineInfo info) { } } - private record LineDrawInfo(int index, TextLayout layout, String text, int offset, int height) { + private record LineDrawInfo(int index, TextLayout layout, String text, int offset, float height) { } @@ -466,7 +466,7 @@ private LineDrawInfo makeLineDrawInfo(int lineIndex) { TextLayout layout = getTextLayout(lineIndex); String text = content.getLine(lineIndex); int offset = content.getOffsetAtLine(lineIndex); - int height = layout.getBounds().height; + float height = layout.getBounds().getHeight(); return new LineDrawInfo(lineIndex, layout, text, offset, height); } @@ -483,6 +483,11 @@ int drawLines(int startLine, int endLine, int begX, int begY, int endY, GC gc, C // still, I'd rather stay safe. final boolean drawBackBeforeFore = (fixedLineMetrics != null); + +// Rectangle bounds = styledText.getClientArea(); +// gc.setBackground(widgetBackground); +// styledText.drawBackground(gc, bounds.x, bounds.y, bounds.width, bounds.height); + if (drawBackBeforeFore) { // Cache drawing information final List drawInfos = new ArrayList<>(); @@ -515,18 +520,18 @@ int drawLines(int startLine, int endLine, int begX, int begY, int endY, GC gc, C return y - begY; } - int y = begY; + float y = begY; for (int iLine = startLine; y < endY && iLine < endLine; iLine++) { LineDrawInfo lineInfo = makeLineDrawInfo(iLine); drawLineBackground(lineInfo, y, gc, widgetBackground); - drawLineForeground(lineInfo, begX, y, gc, widgetForeground); + drawLineForeground(lineInfo, begX, (int) y, gc, widgetForeground); disposeTextLayout(lineInfo.layout); - y += lineInfo.height; + y += lineInfo.height; // Culprit } - return y - begY; + return (int) y - begY; } -private void drawLineBackground(LineDrawInfo lineInfo, int paintY, GC gc, Color widgetBackground) { +private void drawLineBackground(LineDrawInfo lineInfo, float paintY, GC gc, Color widgetBackground) { Rectangle client = styledText.getClientArea(); Color lineBackground = getLineBackground(lineInfo.index, null); StyledTextEvent event = styledText.getLineBackgroundData(lineInfo.offset, lineInfo.text); @@ -536,13 +541,13 @@ private void drawLineBackground(LineDrawInfo lineInfo, int paintY, GC gc, Color if (lineBackground != null) { if (verticalIndent > 0) { gc.setBackground(widgetBackground); - gc.fillRectangle(client.x, paintY, client.width, verticalIndent); + gc.fillRectangle(new Rectangle.OfFloat(client.x, paintY, client.width, verticalIndent)); } gc.setBackground(lineBackground); - gc.fillRectangle(client.x, paintY + verticalIndent, client.width, lineInfo.height - verticalIndent); + gc.fillRectangle(new Rectangle.OfFloat(client.x, paintY + verticalIndent, client.width, lineInfo.height - verticalIndent)); } else { gc.setBackground(widgetBackground); - styledText.drawBackground(gc, client.x, paintY, client.width, lineInfo.height); + styledText.drawBackground(gc, new Rectangle.OfFloat(client.x, paintY, client.width, lineInfo.height)); } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java index 83edb88ff80..0e3992a092c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java @@ -69,6 +69,16 @@ public Point (int x, int y) { this.y = y; } +public float getX() { + return x; +} + +public float getY() { + return y; +} + + + /** * Compares the argument to the receiver, and returns true * if they represent the same object using a class @@ -142,10 +152,12 @@ public OfFloat(float x, float y) { this.residualY = y - this.y; } + @Override public float getX() { return x + residualX; } + @Override public float getY() { return y + residualY; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java index 685f0e09be0..1ae5b9afe65 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java @@ -87,6 +87,28 @@ public Rectangle (int x, int y, int width, int height) { this.height = height; } + + +public float getX() { + return x; +} + + +public float getY() { + return y; +} + + +public float getWidth() { + return width; +} + + +public float getHeight() { + return height; +} + + /** * Destructively replaces the x, y, width and height values * in the receiver with ones which represent the union of the @@ -424,18 +446,22 @@ public OfFloat(float x, float y, float width, float height) { this.residualHeight = height - this.height; } + @Override public float getX() { return x + residualX; } + @Override public float getY() { return y + residualY; } + @Override public float getWidth() { return width + residualWidth; } + @Override public float getHeight() { return height + residualHeight; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index e61fa23614f..1284c8a4421 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -2405,6 +2405,13 @@ public void drawString (String string, int x, int y, boolean isTransparent) { storeAndApplyOperationForExistingHandle(new DrawStringOperation(string, new Point(x, y), isTransparent)); } +public void drawString (String string, Point.OfFloat point, boolean isTransparent) { + checkNonDisposed(); + if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (string.isEmpty()) return; + storeAndApplyOperationForExistingHandle(new DrawStringOperation(string, point, isTransparent)); +} + private class DrawStringOperation extends Operation { private final String string; private final Point location; 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 23f745c6cc8..4851d952012 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 @@ -1799,7 +1799,8 @@ public Rectangle getBounds () { width = Math.max(width, DPIUtil.scaleDown(lineWidthInPixels[line], getZoom()) + getLineIndent(line)); } } - return new Rectangle (0, 0, width, lineY[lineY.length - 1] + getVerticalIndent()); + float height = DPIUtil.scaleDown((float) Math.round(DPIUtil.scaleUp(lineY[lineY.length - 1] + getVerticalIndent(), getZoom())), getZoom()); + return new Rectangle.OfFloat (0, 0, width, height); } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java index 068fa7671ce..816ad351046 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java @@ -108,6 +108,12 @@ public void drawBackground (GC gc, int x, int y, int width, int height) { drawBackgroundInPixels(gc, rectangle.x, rectangle.y, rectangle.width, rectangle.height, 0, 0); } +public void drawBackground (GC gc, Rectangle rectangle) { + int zoom = getZoom(); + Rectangle scaledRectangle = DPIUtil.scaleUp(rectangle, zoom); + drawBackgroundInPixels(gc, scaledRectangle.x, scaledRectangle.y, scaledRectangle.width, scaledRectangle.height, 0, 0); +} + /** * Returns the caret. *