Skip to content

Commit

Permalink
multi zoom level support for pattern for win32
Browse files Browse the repository at this point in the history
This commit contributes to multi zoom level support of pattern using a map of zoom levels with relevant patterns.

Contributes to #62 and #131
  • Loading branch information
amartya4256 committed Jun 6, 2024
1 parent 694c853 commit 37053e2
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ void checkGC(int mask) {
Pattern pattern = data.foregroundPattern;
if (pattern != null) {
if(data.alpha == 0xFF) {
brush = pattern.handle;
brush = pattern.getScaledPattern(getZoom()).handle;
} else {
brush = data.gdipFgPatternBrushAlpha != 0 ? Gdip.Brush_Clone(data.gdipFgPatternBrushAlpha) : createAlphaTextureBrush(pattern.handle, data.alpha);
brush = data.gdipFgPatternBrushAlpha != 0 ? Gdip.Brush_Clone(data.gdipFgPatternBrushAlpha) : createAlphaTextureBrush(pattern.getScaledPattern(getZoom()).handle, data.alpha);
data.gdipFgPatternBrushAlpha = brush;
}
if ((data.style & SWT.MIRRORED) != 0) {
Expand Down Expand Up @@ -289,9 +289,9 @@ void checkGC(int mask) {
Pattern pattern = data.backgroundPattern;
if (pattern != null) {
if(data.alpha == 0xFF) {
data.gdipBrush = pattern.handle;
data.gdipBrush = pattern.getScaledPattern(getZoom()).handle;
} else {
long brush = data.gdipBgPatternBrushAlpha != 0 ? Gdip.Brush_Clone(data.gdipBgPatternBrushAlpha) : createAlphaTextureBrush(pattern.handle, data.alpha);
long brush = data.gdipBgPatternBrushAlpha != 0 ? Gdip.Brush_Clone(data.gdipBgPatternBrushAlpha) : createAlphaTextureBrush(pattern.getScaledPattern(getZoom()).handle, data.alpha);
data.gdipBrush = data.gdipBgBrush /*= data.gdipBgPatternBrushAlpha */ = brush;
}
if ((data.style & SWT.MIRRORED) != 0) {
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 @@ -53,8 +55,19 @@ public class Pattern extends Resource {
*/
public long handle;

private int initialZoom;

private Runnable bitmapDestructor;

private Image image;

private float x1, y1, x2, y2;
private Color color1, color2;
private int alpha1, alpha2;
private final boolean isImagePattern;

private HashMap<Integer, Pattern> scaledPattern = new HashMap<>();

/**
* Constructs a new Pattern given an image. Drawing with the resulting
* pattern will cause the image to be tiled over the resulting area.
Expand Down Expand Up @@ -85,10 +98,19 @@ public class Pattern extends Resource {
*/
public Pattern(Device device, Image image) {
super(device);
isImagePattern = true;
if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
this.device.checkGDIP();
long[] gdipImage = image.createGdipImage();
this.image = image;
initialZoom = DPIUtil.getDeviceZoom();
scaledPattern.put(initialZoom, this);
setImageHandle(image, initialZoom);
init();
}

void setImageHandle(Image image, int zoomLevel) {
long[] gdipImage = image.createGdipImage(zoomLevel);
long img = gdipImage[0];
int width = Gdip.Image_GetWidth(img);
int height = Gdip.Image_GetHeight(img);
Expand All @@ -104,7 +126,6 @@ public Pattern(Device device, Image image) {
bitmapDestructor.run();
SWT.error(SWT.ERROR_NO_HANDLES);
}
init();
}

/**
Expand Down Expand Up @@ -187,10 +208,57 @@ public Pattern(Device device, float x1, float y1, float x2, float y2, Color colo
*/
public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
super(device);
x1 = DPIUtil.autoScaleUp(x1);
y1 = DPIUtil.autoScaleUp(y1);
x2 = DPIUtil.autoScaleUp(x2);
y2 = DPIUtil.autoScaleUp(y2);
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color1 = color1;
this.color2 = color2;
this.alpha1 = alpha1;
this.alpha2 = alpha2;
this.isImagePattern = false;
initialZoom = DPIUtil.getDeviceZoom();
scaledPattern.put(initialZoom, this);
initializeSize(initialZoom);
}

private Pattern(Device device, int zoomLevel, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
super(device);
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color1 = color1;
this.color2 = color2;
this.alpha1 = alpha1;
this.alpha2 = alpha2;
this.isImagePattern = false;
initialZoom = zoomLevel;
scaledPattern.put(initialZoom, this);
initializeSize(initialZoom);
}

Pattern getScaledPattern(int zoomLevel) {
if(zoomLevel == initialZoom) {
return this;
}
if (this.isImagePattern) {
setImageHandle(image, zoomLevel);
return this;
}
if(this.scaledPattern.get(zoomLevel) == null) {
Pattern p = new Pattern(this.device, zoomLevel, x1, y1, x2, y2, color1, alpha1, color2, alpha2);
this.scaledPattern.put(zoomLevel, p);
}
return this.scaledPattern.get(zoomLevel);
}

private void initializeSize(int zoomLevel) {
float x1, y1, x2, y2;
x1 = DPIUtil.autoScaleUp(this.x1, zoomLevel);
y1 = DPIUtil.autoScaleUp(this.y1, zoomLevel);
x2 = DPIUtil.autoScaleUp(this.x2, zoomLevel);
y2 = DPIUtil.autoScaleUp(this.y2, zoomLevel);
if (color1 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (color1.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
if (color2 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
Expand Down Expand Up @@ -224,8 +292,12 @@ public Pattern(Device device, float x1, float y1, float x2, float y2, Color colo
init();
}



@Override
void destroy() {
this.scaledPattern.remove(initialZoom);
this.scaledPattern.values().forEach(Pattern::destroy);
int type = Gdip.Brush_GetType(handle);
switch (type) {
case Gdip.BrushTypeSolidColor:
Expand Down Expand Up @@ -275,4 +347,4 @@ public String toString() {
return "Pattern {" + handle + "}";
}

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

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Pattern;
import org.eclipse.swt.internal.DPIUtil;

public class PatternWin32ManualTest {
private static Display display = Display.getDefault();

public static void main (String [] args) {
int zoom = DPIUtil.getDeviceZoom();
int scaledZoom = zoom * 3;
int width = 400;
int height = 300;
final Pattern pat = new Pattern(display, 0, 0, width, height, new Color(null, 200, 200, 200), 0, new Color(null, 255, 0, 0), 255);

Shell shell = new Shell(display);
shell.setText("Unscaled shell");
shell.setSize(width, height);
shell.addPaintListener(e -> {
e.gc.setBackground(new Color(null, 100, 200, 0));
e.gc.fillRectangle(0, 0, shell.getBounds().width, shell.getBounds().height);
e.gc.setBackground(new Color(null, 255, 0, 0));
e.gc.setBackgroundPattern(pat);
e.gc.fillRectangle(0, 0, shell.getBounds().width, shell.getBounds().height);
});
shell.open();

DPIUtil.setDeviceZoom(scaledZoom);
Shell shell2 = new Shell(display);
shell2.nativeZoom = scaledZoom;
shell2.setText("Scaled shell");
shell2.setSize(width, height);
shell2.addPaintListener(e -> {
e.gc.setBackground(new Color(null, 100, 200, 0));
e.gc.fillRectangle(0, 0, shell2.getBounds().width, shell2.getBounds().height);
e.gc.setBackground(new Color(null, 255, 0, 0));
e.gc.setBackgroundPattern(pat);
e.gc.fillRectangle(0, 0, shell2.getBounds().width, shell2.getBounds().height);
});
shell2.open();

while (!shell.isDisposed() || !shell2.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
pat.dispose();
shell.dispose();
shell2.dispose();
}
}

0 comments on commit 37053e2

Please sign in to comment.