Relative Consistency across Resolutions

I’m creating an application which, for lack of a better analogy, is a bit like PowerPoint (in its output, at least).
My intention is to have the resulting graphics appear relatively consistent on any machine.
By this I mean that a box that takes up 1/3 of the drawing area on the machine on which it was created should take up 1/3 of the drawing area on any machine, and a font size that fits 50 "m"s across the creating machine’s screen should be adjusted to be 50 ems on any target machine.
I guess you could say it’s a little bit like SVG, but I’ll probably want the user to be inputting sizes as pixels, or something close, as this is what will make the most sense to them.

I have a couple of different ideas of how to get everything to be relative to the resolution, and I’d like to ask for comments on how people think they might work.
However, I thought I’d ask for ideas of how other people might do this first.

So, how would you make line/shape/font sizes relative to the resolution?
How would you store the sizes?
How would you use them to draw features and text?

I’ll post my ideas tomorrow for criticism, but I’m keen to know what other people would do.

What you want is resolution independence. Take a look at java.awt.GraphicsConfiguration.getDefaultTransform() and getNormalizingTransform().

In the ideal world, all you’d need to do is to use these two methods to set the transform on your Graphics2D object, and your rendering will be scaled appropriately.

Of course, you’d still need to make sure that you have different image banks for different DPI, since just scaling them won’t look good.

The bad news is that afaik in Sun jdk getDefaultTransform always returns identity. And if we were to fix it to return the correct transform based on the screen dpi, we’d probably break many applications which aren’t DPI-aware.

[quote]What you want is resolution independence. Take a look at java.awt.GraphicsConfiguration.getDefaultTransform() and getNormalizingTransform().

In the ideal world, all you’d need to do is to use these two methods to set the transform on your Graphics2D object, and your rendering will be scaled appropriately.

The bad news is that afaik in Sun jdk getDefaultTransform always returns identity. And if we were to fix it to return the correct transform based on the screen dpi, we’d probably break many applications which aren’t DPI-aware.
[/quote]
It sounds like you’re saying I should use getDefaultTransform() and getNormalizingTransform() except they’re not implemented properly? Or they’re okay, but I have to combine them, not just rely on the default transform? I’m not sure if you are saying this is a possible solution or that it is a theoretical solution that won’t actually work, or won’t look very good? If it’s one of the latter, do you have any other suggestiongs? :smiley:

Not sure what you’re saying there.
I don’t know what “image banks” are.
(Yup, I’m a n00b to complex Java 2D work).
If it matters, I’m not intending to have any sprite-like images. There will be large images involved (e.g. 800x600 and up), but everything else will be primitive shapes and text.

Important:
I should have mentioned in the original post that the application will be doing animation.
Are scaling-based solutions going to work for animation or is it too costly?
(That’s a question for anyone with relevant experience.)

Couldn’t you just use:

Graphics2D.setTransform()

at the start of your rendering method to scale up/down the image as desired? It’d just be a matter of create a scaling transform using:

AffineTransform.getScaleInstance()

base of the expected resolution vs the actual resolution?

Kev

[quote]Couldn’t you just use:

Graphics2D.setTransform()

at the start of your rendering method to scale up/down the image as desired?
[/quote]
I probably could - sounds like a nice, simple solution.
(I really am new to Java2D in this regard!)
This would require me to store the original resolution with the file, but that could work alright.

I assume that, if I use a transform, the drawing is done in the target coord system, after the coordinates are transformed, rather than drawn and then scaled?
Do you know if, internally, it will use doubles to represent the transformed coordinates?
If so, is this going to make straight lines look a bit funny? Like, anti-aliased into the next row/column a bit?

And how does a Transform work with Fonts?
Will it scale a 14 point font to 13.2555 or something?
Or will it draw the string and then scale it down?
And, whatever it does, will it look nice, or will it look like it’s been scaled? :wink:

Thanks for help so far!

Double vs Float depends on the type of primitive you use, for instance Line2D has two inner classes, Line2D.Double and Line2D.Float… allowing you to make the decision.

Text scales fine aswell. I’ve never really had any problems with the scaling performed by Java2D, there might even be a hint that you can pass through to get nice scaling? (I’m sure trembovetski would know :))

If things start to look a little ragged, you can always try switching on antialiasing to smooth the whole thing out (but make it optional since it seems to be an enormous performance hit).

Kev

OK, I’ll give some of the ideas so far a go and see how things turn out.

Thanks for the help.

If anyone has any other, different ideas, or more information, please keep posting! :slight_smile:

Cheers,

Graham.

Okay I’ve tried doing some scaling using jsut AffineTransorm and the results weren’t so good for text.
I drew a string in a panel and then did the same on another panel with a 4d/5d scaling AffineTransform.
The size of the text changes okay, but it was rendered way too bold in the smaller version.
I tried setting a whole bunch of RenderingHints but that didn’t fix the problem.

An idea I’d thought of was Rendering everything to a back buffer way bigger than the original resolution (e.g. x2 in each dimension) and then doing a scaled drawImage to get it onto the screen.
I think this would get me good consistency but I’m thinking the performance might suck doing interpolation from a massive image 50 times a second.

Any opinions on whether this is a good idea or bad?