benfry / processing4

Processing 4.x releases for Java 17
https://processing.org
Other
1.34k stars 239 forks source link

screenX etc. "broken" with pixelDensity(2) combined with JAVA2D renderer #557

Open clankill3r opened 2 years ago

clankill3r commented 2 years ago

The following code:

void setup() {
  size(600, 600, JAVA2D);
  pixelDensity(2);
  println(screenX(600, 0));
}

prints out 1200.

If I change the pixelDensity to 1 it prints out 600.

For P2D and P3D it will always be 600, no matter the pixelDensity (like it should be).

I compared the screenXImpl here are the results (not sure if this helps):

JAVA2D with pixelDensity 1

_JAVA2D_PD1

JAVA2D with pixelDensity 2

_JAVA2D_PD2

P2D with pixelDensity 1

_P2D_PD1

P2D with pixelDensity 2

_P2D_PD2

My first impression is that the pixelDensity 2 for JAVA2D is bit of a cheap hack. (But what do I know!).

benfry commented 2 years ago

Not sure what you mean by cheap hack—supporting high-density and regular density displays is an exceptionally complicated thing to get right without breaking everyone's code.

I'm not actually sure what the right solution here would be: when pixelDensity(2) has been called, all operations with pixels operate in 2x space, (i.e. get(), set(), etc.) The screenX() command is right in the middle: on one hand, it's literally referencing a pixel on the screen, so it should be doubled (that's why it's done this way for JAVA2D). On the other hand, you could argue that those are operations are typically being used to reference placement in non-pixel space.

For instance, if we changed it to not be doubled as you suggest, folks are gonna be disappointed when they use screenX() and screenY() and can't pass that value to get() to get the color of a location on screen.

So the bug here is that it's not consistent, but we'll have to give it some thought about which solution to make consistent.