Skip to content

Commit

Permalink
Multi Zoom Level feature in transform for win32
Browse files Browse the repository at this point in the history
This commit implements the mean to provide different handles of a transform object at different zoom levels which can be consumed by GC depending on the zoom level available within its GCData.

Contributes to #62 and #127
  • Loading branch information
amartya4256 committed Jun 12, 2024
1 parent 4c4074f commit c35ce40
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3792,10 +3792,10 @@ public void getTransform(Transform transform) {
if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
long gdipGraphics = data.gdipGraphics;
if (gdipGraphics != 0) {
Gdip.Graphics_GetTransform(gdipGraphics, transform.handle);
Gdip.Graphics_GetTransform(gdipGraphics, Transform.win32_getHandle(transform, getZoom()));
long identity = identity();
Gdip.Matrix_Invert(identity);
Gdip.Matrix_Multiply(transform.handle, identity, Gdip.MatrixOrderAppend);
Gdip.Matrix_Multiply(Transform.win32_getHandle(transform, getZoom()), identity, Gdip.MatrixOrderAppend);
Gdip.Matrix_delete(identity);
} else {
transform.setElements(1, 0, 0, 1, 0, 0);
Expand Down Expand Up @@ -4930,7 +4930,7 @@ public void setTransform(Transform transform) {
initGdip();
long identity = identity();
if (transform != null) {
Gdip.Matrix_Multiply(identity, transform.handle, Gdip.MatrixOrderPrepend);
Gdip.Matrix_Multiply(identity, Transform.win32_getHandle(transform, getZoom()), Gdip.MatrixOrderPrepend);
}
Gdip.Graphics_SetTransform(data.gdipGraphics, identity);
Gdip.Matrix_delete(identity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.swt.graphics;

import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gdip.*;
Expand Down Expand Up @@ -51,6 +53,11 @@ public class Transform extends Resource {
*/
public long handle;

private int initalZoom;


private HashMap<Integer, Long> handleMap = new HashMap<>();

/**
* Constructs a new identity Transform.
* <p>
Expand Down Expand Up @@ -146,10 +153,12 @@ public Transform(Device device, float[] elements) {
*/
public Transform (Device device, float m11, float m12, float m21, float m22, float dx, float dy) {
super(device);
initalZoom = DPIUtil.getDeviceZoom();
this.device.checkGDIP();
handle = Gdip.Matrix_new(m11, m12, m21, m22,
DPIUtil.autoScaleUp(this.device, dx), DPIUtil.autoScaleUp(this.device, dy));
handle = Gdip.Matrix_new(m11, m12, m21, m22,
DPIUtil.autoScaleUp(this.device, dx, initalZoom), DPIUtil.autoScaleUp(this.device, dy, initalZoom));
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
handleMap.put(initalZoom, handle);
init();
}

Expand All @@ -161,7 +170,7 @@ static float[] checkTransform(float[] elements) {

@Override
void destroy() {
Gdip.Matrix_delete(handle);
handleMap.values().forEach(handle -> Gdip.Matrix_delete(handle));
handle = 0;
}

Expand All @@ -185,8 +194,8 @@ public void getElements(float[] elements) {
if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
Gdip.Matrix_GetElements(handle, elements);
Drawable drawable = getDevice();
elements[4] = DPIUtil.autoScaleDown(drawable, elements[4]);
elements[5] = DPIUtil.autoScaleDown(drawable, elements[5]);
elements[4] = DPIUtil.scaleDown(drawable, elements[4], initalZoom);
elements[5] = DPIUtil.scaleDown(drawable, elements[5], initalZoom);
}

/**
Expand Down Expand Up @@ -297,7 +306,7 @@ public void rotate(float angle) {
*/
public void scale(float scaleX, float scaleY) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Gdip.Matrix_Scale(handle, scaleX, scaleY, Gdip.MatrixOrderPrepend);
Gdip.Matrix_Scale(handle, DPIUtil.autoScaleUp(scaleX, initalZoom), DPIUtil.autoScaleUp(scaleY, initalZoom), Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -318,8 +327,7 @@ public void scale(float scaleX, float scaleY) {
public void setElements(float m11, float m12, float m21, float m22, float dx, float dy) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Drawable drawable = getDevice();
Gdip.Matrix_SetElements(handle, m11, m12, m21, m22,
DPIUtil.autoScaleUp(drawable, dx), DPIUtil.autoScaleUp(drawable, dy));
Gdip.Matrix_SetElements(handle, m11, m12, m21, m22, DPIUtil.autoScaleUp(drawable, dx, initalZoom), DPIUtil.autoScaleUp(drawable, dy, initalZoom));
}

/**
Expand Down Expand Up @@ -360,11 +368,11 @@ public void transform(float[] pointArray) {
int length = pointArray.length;
Drawable drawable = getDevice();
for (int i = 0; i < length; i++) {
pointArray[i] = DPIUtil.autoScaleUp(drawable, pointArray[i]);
pointArray[i] = DPIUtil.autoScaleUp(drawable, pointArray[i], initalZoom);
}
Gdip.Matrix_TransformPoints(handle, pointArray, length / 2);
for (int i = 0; i < length; i++) {
pointArray[i] = DPIUtil.autoScaleDown(drawable, pointArray[i]);
pointArray[i] = DPIUtil.scaleDown(drawable, pointArray[i], initalZoom);
}
}

Expand All @@ -382,7 +390,7 @@ public void transform(float[] pointArray) {
public void translate(float offsetX, float offsetY) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Drawable drawable = getDevice();
Gdip.Matrix_Translate(handle, DPIUtil.autoScaleUp(drawable, offsetX), DPIUtil.autoScaleUp(drawable, offsetY), Gdip.MatrixOrderPrepend);
Gdip.Matrix_Translate(handle, DPIUtil.autoScaleUp(drawable, offsetX, initalZoom), DPIUtil.autoScaleUp(drawable, offsetY, initalZoom), Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -399,4 +407,27 @@ public String toString() {
return "Transform {" + elements [0] + "," + elements [1] + "," +elements [2] + "," +elements [3] + "," +elements [4] + "," +elements [5] + "}";
}

/**
* the handle to the OS resource for the right zoom level
* <p>
* <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
* public API. It is marked public only so that it can be shared
* within the packages provided by SWT. It is not available on all
* platforms and should never be accessed from application code.
* </p>
*
* @noreference This field is not intended to be referenced by clients.
*/
public static long win32_getHandle(Transform transform, int zoomLevel) {
if(transform.handleMap.get(zoomLevel) == null) {
float[] elements = new float[6];
transform.getElements(elements);
elements[4] = DPIUtil.autoScaleUp(transform.device, DPIUtil.scaleDown(transform.device, elements[4], transform.initalZoom), zoomLevel);
elements[5] = DPIUtil.autoScaleUp(transform.device, DPIUtil.scaleDown(transform.device, elements[5], transform.initalZoom), zoomLevel);

transform.handleMap.put(zoomLevel, Gdip.Matrix_new(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]));
}
return transform.handleMap.get(zoomLevel);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.eclipse.swt.graphics;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import org.eclipse.swt.internal.DPIUtil;
import org.eclipse.swt.internal.gdip.Gdip;
import org.eclipse.swt.widgets.Display;
import org.junit.Before;
import org.junit.Test;

public class TransformWin32Tests {
private Display display;

@Before
public void setUp() {
display = Display.getDefault();
}

@Test
public void shouldHaveDifferentHandlesAtDifferentZoomLevels() {
int zoom = DPIUtil.getDeviceZoom();
Transform transform = new Transform(display);
long scaledHandle = Transform.win32_getHandle(transform, zoom * 2);
assertNotEquals("There exist different handles for different zoom levels", scaledHandle, transform.handle);
long scaledHandle2 = Transform.win32_getHandle(transform, zoom * 3);
assertNotEquals("There exist different handles for different zoom levels", scaledHandle, scaledHandle2);
}

@Test
public void scaledTrasformMustHaveScaledValues() {
int zoom = DPIUtil.getDeviceZoom();
Transform transform = new Transform(display, 0, 0, 0, 0, 4, 2);
float[] elements = new float[6];
transform.getElements(elements);
long scaledHandle = Transform.win32_getHandle(transform, zoom * 2);
float[] scaledElements = new float[6];
Gdip.Matrix_GetElements(scaledHandle, scaledElements);
assertEquals(elements[4] * 2, scaledElements[4], 0);
}

}

0 comments on commit c35ce40

Please sign in to comment.