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 20, 2024
1 parent 7ac43c0 commit bc1b223
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*******************************************************************************
* 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 static org.junit.Assert.assertNotEquals;

import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gdip.*;
import org.junit.*;

public class TransformWin32Tests extends Win32AutoscaleTestBase {

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

@Test
public void testScaledTrasformMustHaveScaledValues() {
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.getHandle(zoom * 2);
float[] scaledElements = new float[6];
Gdip.Matrix_GetElements(scaledHandle, scaledElements);
assertEquals(elements[4] * 2, scaledElements[4], 0);
assertEquals(elements[5] * 2, scaledElements[5], 0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3790,10 +3790,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.getHandle(getZoom()));
long identity = identity();
Gdip.Matrix_Invert(identity);
Gdip.Matrix_Multiply(transform.handle, identity, Gdip.MatrixOrderAppend);
Gdip.Matrix_Multiply(transform.getHandle(getZoom()), identity, Gdip.MatrixOrderAppend);
Gdip.Matrix_delete(identity);
} else {
transform.setElements(1, 0, 0, 1, 0, 0);
Expand Down Expand Up @@ -4928,7 +4928,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.getHandle(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 All @@ -37,19 +39,9 @@
*/
public class Transform extends Resource {

/**
* the OS resource for the Transform
* (Warning: This field is platform dependent)
* <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 long handle;
private int initialZoom;

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

/**
* Constructs a new identity Transform.
Expand Down Expand Up @@ -146,10 +138,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);
initialZoom = DPIUtil.getDeviceZoom();
this.device.checkGDIP();
handle = Gdip.Matrix_new(m11, m12, m21, m22,
DPIUtil.autoScaleUp(this.device, dx), DPIUtil.autoScaleUp(this.device, dy));
long handle = Gdip.Matrix_new(m11, m12, m21, m22,
DPIUtil.autoScaleUp(this.device, dx, initialZoom), DPIUtil.autoScaleUp(this.device, dy, initialZoom));
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
zoomLevelToHandle.put(initialZoom, handle);
init();
}

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

@Override
void destroy() {
Gdip.Matrix_delete(handle);
handle = 0;
zoomLevelToHandle.values().forEach(Gdip::Matrix_delete);
zoomLevelToHandle.clear();
}

/**
Expand All @@ -183,10 +177,10 @@ public void getElements(float[] elements) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
Gdip.Matrix_GetElements(handle, elements);
Gdip.Matrix_GetElements(getHandle(initialZoom), 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], initialZoom);
elements[5] = DPIUtil.scaleDown(drawable, elements[5], initialZoom);
}

/**
Expand All @@ -201,7 +195,7 @@ public void getElements(float[] elements) {
*/
public void identity() {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Gdip.Matrix_SetElements(handle, 1, 0, 0, 1, 0, 0);
Gdip.Matrix_SetElements(getHandle(initialZoom), 1, 0, 0, 1, 0, 0);
}

/**
Expand All @@ -215,7 +209,7 @@ public void identity() {
*/
public void invert() {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (Gdip.Matrix_Invert(handle) != 0) SWT.error(SWT.ERROR_CANNOT_INVERT_MATRIX);
if (Gdip.Matrix_Invert(getHandle(initialZoom)) != 0) SWT.error(SWT.ERROR_CANNOT_INVERT_MATRIX);
}

/**
Expand All @@ -230,7 +224,7 @@ public void invert() {
*/
@Override
public boolean isDisposed() {
return handle == 0;
return zoomLevelToHandle.isEmpty();
}

/**
Expand All @@ -241,7 +235,7 @@ public boolean isDisposed() {
*/
public boolean isIdentity() {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
return Gdip.Matrix_IsIdentity(handle);
return Gdip.Matrix_IsIdentity(getHandle(initialZoom));
}

/**
Expand All @@ -263,7 +257,7 @@ public void multiply(Transform matrix) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (matrix == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (matrix.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
Gdip.Matrix_Multiply(handle, matrix.handle, Gdip.MatrixOrderPrepend);
Gdip.Matrix_Multiply(getHandle(initialZoom), matrix.getHandle(initialZoom), Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -281,7 +275,7 @@ public void multiply(Transform matrix) {
*/
public void rotate(float angle) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Gdip.Matrix_Rotate(handle, angle, Gdip.MatrixOrderPrepend);
Gdip.Matrix_Rotate(getHandle(initialZoom), angle, Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -297,7 +291,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(getHandle(initialZoom), scaleX, scaleY, Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -318,8 +312,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(getHandle(initialZoom), m11, m12, m21, m22, DPIUtil.autoScaleUp(drawable, dx, initialZoom), DPIUtil.autoScaleUp(drawable, dy, initialZoom));
}

/**
Expand All @@ -337,7 +330,7 @@ public void setElements(float m11, float m12, float m21, float m22, float dx, fl
*/
public void shear(float shearX, float shearY) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
Gdip.Matrix_Shear(handle, shearX, shearY, Gdip.MatrixOrderPrepend);
Gdip.Matrix_Shear(getHandle(initialZoom), shearX, shearY, Gdip.MatrixOrderPrepend);
}

/**
Expand All @@ -360,11 +353,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], initialZoom);
}
Gdip.Matrix_TransformPoints(handle, pointArray, length / 2);
Gdip.Matrix_TransformPoints(getHandle(initialZoom), pointArray, length / 2);
for (int i = 0; i < length; i++) {
pointArray[i] = DPIUtil.autoScaleDown(drawable, pointArray[i]);
pointArray[i] = DPIUtil.scaleDown(drawable, pointArray[i], initialZoom);
}
}

Expand All @@ -382,7 +375,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(getHandle(initialZoom), DPIUtil.autoScaleUp(drawable, offsetX, initialZoom), DPIUtil.autoScaleUp(drawable, offsetY, initialZoom), Gdip.MatrixOrderPrepend);
}

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

long getHandle(int zoomLevel) {
if(zoomLevelToHandle.get(zoomLevel) == null) {
float[] elements = new float[6];
getElements(elements);
elements[4] = DPIUtil.autoScaleUp(device, DPIUtil.scaleDown(device, elements[4], initialZoom), zoomLevel);
elements[5] = DPIUtil.autoScaleUp(device, DPIUtil.scaleDown(device, elements[5], initialZoom), zoomLevel);

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

}

0 comments on commit bc1b223

Please sign in to comment.