Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of transform to enable Multi Zoom Level Support for Win32 #1276

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;

amartya4256 marked this conversation as resolved.
Show resolved Hide resolved
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);
}

}
Loading