Skip to content

Commit

Permalink
Multi zoom level support of GC for win32
Browse files Browse the repository at this point in the history
This commit contributes to multi zoom level support of GC which can be extended by other resources and widgets.

Contributes to
#62 and #131
  • Loading branch information
amartya4256 authored and HeikoKlare committed Jun 6, 2024
1 parent 7e60295 commit 2ea5502
Show file tree
Hide file tree
Showing 16 changed files with 271 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,10 @@ public static boolean isAutoScaleOnRuntimeActive() {
return autoScaleOnRuntime;
}

static boolean setAutoScaleOnRuntimeActive(boolean value) {
return autoScaleOnRuntime = value;
}

/**
* AutoScale ImageDataProvider.
*/
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public final class GCData {
public float[] lineDashes;
public float lineMiterLimit = 10;
public int alpha = 0xFF;
public int nativeZoom;

public Image image;
public PAINTSTRUCT ps;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2154,6 +2154,7 @@ public long internal_new_GC (GCData data) {
data.style |= SWT.LEFT_TO_RIGHT;
}
data.device = device;
data.nativeZoom = currentNativeZoom;
data.image = this;
data.font = Font.win32_new(device.getSystemFont(), DPIUtil.getNativeDeviceZoom());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,7 @@ LRESULT wmNotifyChild (NMHDR hdr, long wParam, long lParam) {
if (image != null) {
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);

int margin = computeLeftMargin();
Rectangle imageBounds = DPIUtil.autoScaleBounds(image.getBounds(), this.getZoom(), 100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ LRESULT WM_PAINT (long wParam, long lParam) {
OS.SetRect (rect, ps.left, ps.top, ps.right, ps.bottom);
drawBackground (phdc [0], rect);
}
GC gc = GC.win32_new (phdc [0], data);
GC gc = createNewGC(phdc [0], data);
Event event = new Event ();
event.gc = gc;
event.setBoundsInPixels(new Rectangle(ps.left, ps.top, width, height));
Expand Down Expand Up @@ -1697,7 +1697,7 @@ LRESULT WM_PRINTCLIENT (long wParam, long lParam) {
data.background = control.getBackgroundPixel ();
data.font = Font.win32_new(display, OS.SendMessage (handle, OS.WM_GETFONT, 0, 0));
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (wParam, data);
GC gc = createNewGC(wParam, data);
Event event = new Event ();
event.gc = gc;
event.setBoundsInPixels(new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,7 @@ public long internal_new_GC (GCData data) {
}
}
data.device = display;
data.nativeZoom = nativeZoom;
int foreground = getForegroundPixel ();
if (foreground != OS.GetTextColor (hDC)) data.foreground = foreground;
Control control = findBackgroundControl ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2748,6 +2748,7 @@ public long internal_new_GC (GCData data) {
} else {
data.style |= SWT.LEFT_TO_RIGHT;
}
data.nativeZoom = getPrimaryMonitor().getZoom();
data.device = this;
data.font = getSystemFont ();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ LRESULT WM_PRINTCLIENT (long wParam, long lParam) {
GCData data = new GCData ();
data.device = display;
data.foreground = getForegroundPixel ();
GC gc = GC.win32_new (wParam, data);
GC gc = createNewGC(wParam, data);
drawWidget (gc, rect);
gc.dispose ();
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ void wmDrawChildImage(DRAWITEMSTRUCT struct) {

GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (struct.hDC, data);
GC gc = createNewGC(struct.hDC, data);
Image image = getEnabled () ? this.image : new Image (display, this.image, SWT.IMAGE_DISABLE);
gc.drawImage (image, DPIUtil.autoScaleDown(x), DPIUtil.autoScaleDown(Math.max (0, (height - imageRect.height) / 2)));
if (image != this.image) image.dispose ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ LRESULT wmDrawChild (long wParam, long lParam) {
if (image != null) {
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (struct.hDC, data);
GC gc = createNewGC(struct.hDC, data);
/*
* Bug in Windows. When a bitmap is included in the
* menu bar, the HDC seems to already include the left
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3464,7 +3464,7 @@ void sendEraseItemEvent (TableItem item, NMLVCUSTOMDRAW nmcd, long lParam, Event
data.font = item.getFont (nmcd.iSubItem);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
int nSavedDC = OS.SaveDC (hDC);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
RECT cellRect = item.getBounds ((int)nmcd.dwItemSpec, nmcd.iSubItem, true, true, true, true, hDC);
Event event = new Event ();
event.item = item;
Expand Down Expand Up @@ -3599,7 +3599,7 @@ Event sendEraseItemEvent (TableItem item, NMTTCUSTOMDRAW nmcd, int column, RECT
data.background = OS.GetBkColor (nmcd.hdc);
data.font = item.getFont (column);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
Event event = new Event ();
event.item = item;
event.index = column;
Expand All @@ -3620,7 +3620,7 @@ Event sendMeasureItemEvent (TableItem item, int row, int column, long hDC) {
data.device = display;
data.font = item.getFont (column);
int nSavedDC = OS.SaveDC (hDC);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
RECT itemRect = item.getBounds (row, column, true, true, false, false, hDC);
Event event = new Event ();
event.item = item;
Expand Down Expand Up @@ -3907,7 +3907,7 @@ void sendPaintItemEvent (TableItem item, NMLVCUSTOMDRAW nmcd) {
}
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
int nSavedDC = OS.SaveDC (hDC);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
RECT itemRect = item.getBounds ((int)nmcd.dwItemSpec, nmcd.iSubItem, true, true, false, false, hDC);
Event event = new Event ();
event.item = item;
Expand Down Expand Up @@ -3948,7 +3948,7 @@ Event sendPaintItemEvent (TableItem item, NMTTCUSTOMDRAW nmcd, int column, RECT
data.foreground = OS.GetTextColor (nmcd.hdc);
data.background = OS.GetBkColor (nmcd.hdc);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
Event event = new Event ();
event.item = item;
event.index = column;
Expand Down Expand Up @@ -6964,7 +6964,7 @@ LRESULT wmNotifyHeader (NMHDR hdr, long wParam, long lParam) {
if (columns[i].image != null) {
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
int y = Math.max (0, (nmcd.bottom - columns[i].image.getBoundsInPixels().height) / 2);
gc.drawImage (columns[i].image, DPIUtil.autoScaleDown(x), DPIUtil.autoScaleDown(y));
x += columns[i].image.getBoundsInPixels().width + 12;
Expand Down Expand Up @@ -7286,7 +7286,7 @@ LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW nmcd, long lParam) {
data.foreground = OS.GetTextColor (nmcd.hdc);
data.background = OS.GetBkColor (nmcd.hdc);
data.font = Font.win32_new (display, hFont);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
int x = cellRect.left;
if (pinfo.iSubItem != 0) x -= gridWidth;
Image image = item.getImage (pinfo.iSubItem);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
if (!ignoreDrawForeground) {
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
RECT iconRect = item.getBounds (index, false, true, false, false, true, hDC); // Pixels
gc.setClipping (DPIUtil.autoScaleDown(new Rectangle(iconRect.left, iconRect.top, iconRect.right - iconRect.left, iconRect.bottom - iconRect.top)));
gc.drawImage (image, 0, 0, bounds.width, bounds.height, DPIUtil.autoScaleDown(iconRect.left), DPIUtil.autoScaleDown(iconRect.top), size.x, size.y);
Expand Down Expand Up @@ -625,7 +625,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
}
data.font = item.getFont (index);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
Event event = new Event ();
event.item = item;
event.index = index;
Expand Down Expand Up @@ -768,7 +768,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
int x1 = Math.max (rect.left, rect.left - inset + 1);
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
gc.setClipping (DPIUtil.autoScaleDown(new Rectangle(x1, rect.top, rect.right - x1, rect.bottom - rect.top)));
gc.drawImage (image, 0, 0, bounds.width, bounds.height, DPIUtil.autoScaleDown(x1), DPIUtil.autoScaleDown(y1), size.x, size.y);
OS.SelectClipRgn (hDC, 0);
Expand Down Expand Up @@ -841,7 +841,7 @@ LRESULT CDDS_ITEMPOSTPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
if (clrTextBk != -1) data.background = clrTextBk;
}
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
Event event = new Event ();
event.item = item;
event.index = index;
Expand Down Expand Up @@ -1063,7 +1063,7 @@ LRESULT CDDS_ITEMPREPAINT (NMTVCUSTOMDRAW nmcd, long wParam, long lParam) {
}
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
data.font = item.getFont (index);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
Event event = new Event ();
event.index = index;
event.item = item;
Expand Down Expand Up @@ -4523,7 +4523,7 @@ Event sendEraseItemEvent (TreeItem item, NMTTCUSTOMDRAW nmcd, int column, RECT c
data.background = OS.GetBkColor (nmcd.hdc);
data.font = item.getFont (column);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
Event event = new Event ();
event.item = item;
event.index = column;
Expand All @@ -4545,7 +4545,7 @@ Event sendMeasureItemEvent (TreeItem item, int index, long hDC, int detail) {
GCData data = new GCData ();
data.device = display;
data.font = item.getFont (index);
GC gc = GC.win32_new (hDC, data);
GC gc = createNewGC(hDC, data);
Event event = new Event ();
event.item = item;
event.gc = gc;
Expand Down Expand Up @@ -4579,7 +4579,7 @@ Event sendPaintItemEvent (TreeItem item, NMTTCUSTOMDRAW nmcd, int column, RECT i
data.foreground = OS.GetTextColor (nmcd.hdc);
data.background = OS.GetBkColor (nmcd.hdc);
data.uiState = (int)OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
Event event = new Event ();
event.item = item;
event.index = column;
Expand Down Expand Up @@ -7925,7 +7925,7 @@ LRESULT wmNotifyHeader (NMHDR hdr, long wParam, long lParam) {
if (columns[i].image != null) {
GCData data = new GCData();
data.device = display;
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
Rectangle imageBounds = DPIUtil.autoScaleBounds(columns[i].image.getBounds(), this.getZoom(), 100);
int y = Math.max (0, (nmcd.bottom - imageBounds.height) / 2);
gc.drawImage (columns[i].image, DPIUtil.autoScaleDown(x), DPIUtil.autoScaleDown(y));
Expand Down Expand Up @@ -8214,7 +8214,7 @@ LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW nmcd, long lParam) {
data.foreground = OS.GetTextColor (nmcd.hdc);
data.background = OS.GetBkColor (nmcd.hdc);
data.font = Font.win32_new (display, hFont);
GC gc = GC.win32_new (nmcd.hdc, data);
GC gc = createNewGC(nmcd.hdc, data);
int x = cellRect [0].left + INSET;
if (index [0] != 0) x -= gridWidth;
Image image = item [0].getImage (index [0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2647,6 +2647,11 @@ void notifyDisposalTracker() {
}
}

GC createNewGC(long hDC, GCData data) {
data.nativeZoom = nativeZoom;
return GC.win32_new(hDC, data);
}

int getZoom() {
return DPIUtil.getZoomForAutoscaleProperty(nativeZoom);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2024 Yatta Solutions
*
* 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:
* Yatta Solutions - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.graphics;

import static org.junit.Assert.assertEquals;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.swt.SWT;
import org.eclipse.swt.internal.DPITestUtil;
import org.eclipse.swt.internal.DPIUtil;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class GCWin32Tests {
private Display display;
private boolean autoScaleOnRuntime;

@Before
public void setUp() {
autoScaleOnRuntime = DPIUtil.isAutoScaleOnRuntimeActive();
DPITestUtil.setAutoScaleOnRunTime(true);
display = Display.getDefault();
}

@After
public void tearDown() {
DPITestUtil.setAutoScaleOnRunTime(autoScaleOnRuntime);
}

@Test
public void gcZoomLevelMustChangeOnShellZoomChange() {
CompletableFuture<Integer> gcNativeZoom = new CompletableFuture<>();
CompletableFuture<Integer> scaledGcNativeZoom = new CompletableFuture<>();
int zoom = DPIUtil.getDeviceZoom();
AtomicBoolean isScaled = new AtomicBoolean(false);
Shell shell = new Shell(display);
shell.addListener(SWT.Paint, event -> {
if (isScaled.get()) {
scaledGcNativeZoom.complete(event.gc.getGCData().nativeZoom);
} else {
gcNativeZoom.complete(event.gc.getGCData().nativeZoom);
}
});

shell.open();
assertEquals("GCData must have a zoom level equal to the actual zoom level of the widget/shell", DPIUtil.getNativeDeviceZoom(), (int) gcNativeZoom.join());

int newSWTZoom = zoom * 2;
Event swtEvent = new Event();
swtEvent.type = SWT.ZoomChanged;
swtEvent.widget = shell;
swtEvent.detail = newSWTZoom;
shell.notifyListeners(SWT.ZoomChanged, swtEvent);
isScaled.set(true);
shell.setVisible(false);
shell.setVisible(true);

assertEquals("GCData must have a zoom level equal to the actual zoom level of the widget/shell on zoomChanged event", newSWTZoom, (int) scaledGcNativeZoom.join());
}

@Test
public void drawnElementsShouldScaleUpToTheRightZoomLevel() {
int zoom = DPIUtil.getDeviceZoom();
int scalingFactor = 2;
Shell shell = new Shell(display);
GC gc = GC.win32_new(shell, new GCData());
gc.getGCData().nativeZoom = zoom * scalingFactor;
gc.getGCData().lineWidth = 10;
assertEquals("DPIUtil calls with getDeviceZoom should scale to the right value", gc.getGCData().lineWidth, gc.getLineWidth() * scalingFactor, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.eclipse.swt.internal;

public class DPITestUtil {

public static void setAutoScaleOnRunTime(boolean value) {
DPIUtil.setAutoScaleOnRuntimeActive(value);
}

}

0 comments on commit 2ea5502

Please sign in to comment.