Re: [JAVA2D] How to keep the rasterizer at bay when printing?

2007-08-24 Thread Olivier Lefevre
> Since (surprise) 'pdl'  didn't help try 'raster', which is the opposite
> of what you  think is helpful but might be interesting.

Thanks for the answer but I think the sarcasm is misplaced. Pease google
"sun.java2d.print.pipeline" and see for yourself how much information
you get. I could not find a list the possible values nor an explanation
of what they do, only a hint that pdl might be a good idea.

>> Furthermore it seems this decision reflects late 1990s thinking re. the
>> capabilities and speed of some printers. Isn't it time to revisit?
>
> No, its the late eighties Microsoft APIs that limit what we can do.

How do the MS APIs come into the picture? Unless we are talking about
so-called Windows printers that render on the desktop and thus using GDI,
I would not think they are involved. To be sure they are an important
use case but they are not even the majority of printers.

In any case the point is not just printers: you can "print" or "paint"
to Graphics2D instances that generate PostScript, PDF, SVG or whatever
and it is extremely unhelpful when they are sent a bitmap instead of
the expected graphics instructions that you put in your code. There
ought to be a switch to turn off rasterization *unconditionally* and
ensure graphics command are sent exactly as they are written. As it
is, the only way I could find to do that is to bypass the high-level
print/paint methods and call paintCompoment and paintBorder directly.
That works but then I have to perform nested widget placment, background
printing etc manually, which is quite a bother. Is there a better way
that I have overlooked?

Regards,

-- O.L.

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


Re: [JAVA2D] How to keep the rasterizer at bay when printing?

2007-08-24 Thread Phil Race

Olivier Lefevre wrote:

Since (surprise) 'pdl'  didn't help try 'raster', which is the opposite
of what you  think is helpful but might be interesting.


Thanks for the answer but I think the sarcasm is misplaced. Pease google
"sun.java2d.print.pipeline" and see for yourself how much information
you get. I could not find a list the possible values nor an explanation
of what they do, only a hint that pdl might be a good idea.


Well since this is internal implementation of the Sun JDK, and not in fact
a standard property its not surprising its not documented.
Its principle use is internal testing.

Generating "PDL" graphics instructions ie NOT a rasterised bitmap
is what the JDK does by default and strives to do whenever it can.

So specifying PDL is either a no-op, or is possibly going to
cause a failure at runtime since you are forcing an inappropriate path.





Furthermore it seems this decision reflects late 1990s thinking re. the
capabilities and speed of some printers. Isn't it time to revisit?

No, its the late eighties Microsoft APIs that limit what we can do.


How do the MS APIs come into the picture? Unless we are talking about
so-called Windows printers that render on the desktop and thus using GDI,
I would not think they are involved. To be sure they are an important
use case but they are not even the majority of printers.


I don't know what you are driving at.
The standard way to print graphics on windows is via GDI,
unless perhaps you are a .NET app, but even then I'll bet its
translated into GDI under the covers as that's what the windows
printer driver API wants.

And GDI doesn't have an API to create a translucent color

Color c = new Color(255,255,255,128);

simply isn't available.

So things like that force a bitmap but I am doubtful its relevant
to your case :



In any case the point is not just printers: you can "print" or "paint"
to Graphics2D instances that generate PostScript, PDF, SVG or whatever
and it is extremely unhelpful when they are sent a bitmap instead of
the expected graphics instructions that you put in your code. There
ought to be a switch to turn off rasterization *unconditionally* and
ensure graphics command are sent exactly as they are written. As it
is, the only way I could find to do that is to bypass the high-level
print/paint methods and call paintCompoment and paintBorder directly.
That works but then I have to perform nested widget placment, background
printing etc manually, which is quite a bother. Is there a better way
that I have overlooked?


Ah! I suspect this is your application bug.

Are you seeing this only when printing a Swing UI?
How are you printing?

Are you calling "component.paint(printerGraphics) on the printer graphics.

Remember that Swing is double-buffered by default so
it does all its painting to an off screen image and that
"printerGraphics" for the printer sees only the resulting image.
So its nothing to do with the printing implementation.

You need to call Component.print() or Component.printAll() in which
case Swing renders directly to the printer graphics.

-phil.





Regards,

-- O.L.



===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed

2007-08-24 Thread Jim Graham

All of this discussion happened while I was away on vacation.  The code
that came up was pretty much what I tend to use for clamping without
branches, but there are a couple of things to note for this particular
application:

It's only valid for values that overflow in the range MININT=>511 and it
only clamps to the output range 0=>255.

The reason for the first constraint is that c<<23 only sets the high
order bit if the overflow stays under 512.  If you get up to 512 then
the 9th bit is clear again and the "clamp to 255" part fails.  (Though,
it will also correctly clamp values between 768 and 1023 and every other
256-sized range of overflow values up to MAXINT - i.e. the ones that
manage to have the 9th bit set...)

The reason for the second constraint is because of the assumptions in
how the math was constructed.

The first constraint may not be a problem if the Cubic Interpolation
values can never cause the value to sum up to 2x the maximum value for a
component which is probably true, but depends on the cubic formula used
to generate the interpolation coefficients (there are a few such
formulas in common use) and so needs to be proven for a given formula.

The second constraint doesn't seem like a problem if you are always
dealing with 8-bit values which is very typical for today's computer
graphics, except for one issue which has been ignored.

The issue is that image interpolation should really be done in a
premultiplied form - as should alpha compositing.  The reason for this
is that if you blend the 4 components (Alpha, R, G, and B) separately in
a non-premultiplied form then a transparent pixel with a non-zero value
in, say, its red component will contribute some red tinting to the final
answer even though it was transparent and should not have contributed
any energy in the first place.

Java2D, for example, does linear and cubic interpolation internally in
the premultiplied form in the Graphics2D implementation for this reason.

Why is this an issue for the clamping equations?  The reason is that if
your accumulation values are premultiplied then the alpha component
needs to be clamped to 0=>255, but the color components need to be
clamped to the range 0=>alpha.  The different range on the clamping of
the color components means that the proposed equations won't work if you
perform your calculations in the premultiplied form.

What I've used instead is a sequence of operations that can clamp any
input range to an arbitrary 0=>N output range as follows:

c &= ~(c >> 31);
c -= N;
c &= (c >> 31);
c += N;

After the first line c is in the range 0=>MAXINT with all negative
values mapped to 0.  After the second line c is set up so that all valid
values are in the range -N=>0 and all positive values are overflow
values.  After the third line all values are in the range -N=>0 with the
positive values mapped to 0.  After the fourth line all values are
finally in the range 0=>N...

(Also, I believe it uses the same number of ALU instructions as the
c << 23) >> 31) | c) & ~(c>>31))&0xFF formula...)

   ...jim

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed

2007-08-24 Thread Ken Warner

Jim,

EXCELLENT!  I need to do a couple of things then.

1) Check to see if the multiplication by the basis functions can possibly
lead to the kind of values that can possibly cause the kind of overflow 
problems you describe.  I think they might.

2) Generate a test case for the code you provided and post results.

The premultiplication problem will not be an issue for my little interpolator 
since I do not composite.  But it would be for someone trying to use my 
interpolator for another purpose than what it was designed for.

The reason for the existence of my interpolator is that the primary function of 
my cylindrical panorama viewer is to project (the best I can) a cylindrical 
image into a rectified viewport.  Interpolation before or after the projection 
simply doesn't work so the interpolator is integrated into the projection code.

It would have been real nice to be able to hand off a chunk of the cylindrical 
image to a Java2D bi-cubic interpolator and get a nicely interpolated rectified 
viewport but that is impossible.  The corners of the source image chunk are 
stretched in a non-linear fashion to fit the canvas.  It's not a simple resize.

But this is really interesting information.  And maybe someday someone will ask 
me about it and I can sound smart... :-)

Ken

Jim Graham wrote:

All of this discussion happened while I was away on vacation.  The code
that came up was pretty much what I tend to use for clamping without
branches, but there are a couple of things to note for this particular
application:

It's only valid for values that overflow in the range MININT=>511 and it
only clamps to the output range 0=>255.

The reason for the first constraint is that c<<23 only sets the high
order bit if the overflow stays under 512.  If you get up to 512 then
the 9th bit is clear again and the "clamp to 255" part fails.  (Though,
it will also correctly clamp values between 768 and 1023 and every other
256-sized range of overflow values up to MAXINT - i.e. the ones that
manage to have the 9th bit set...)

The reason for the second constraint is because of the assumptions in
how the math was constructed.

The first constraint may not be a problem if the Cubic Interpolation
values can never cause the value to sum up to 2x the maximum value for a
component which is probably true, but depends on the cubic formula used
to generate the interpolation coefficients (there are a few such
formulas in common use) and so needs to be proven for a given formula.

The second constraint doesn't seem like a problem if you are always
dealing with 8-bit values which is very typical for today's computer
graphics, except for one issue which has been ignored.

The issue is that image interpolation should really be done in a
premultiplied form - as should alpha compositing.  The reason for this
is that if you blend the 4 components (Alpha, R, G, and B) separately in
a non-premultiplied form then a transparent pixel with a non-zero value
in, say, its red component will contribute some red tinting to the final
answer even though it was transparent and should not have contributed
any energy in the first place.

Java2D, for example, does linear and cubic interpolation internally in
the premultiplied form in the Graphics2D implementation for this reason.

Why is this an issue for the clamping equations?  The reason is that if
your accumulation values are premultiplied then the alpha component
needs to be clamped to 0=>255, but the color components need to be
clamped to the range 0=>alpha.  The different range on the clamping of
the color components means that the proposed equations won't work if you
perform your calculations in the premultiplied form.

What I've used instead is a sequence of operations that can clamp any
input range to an arbitrary 0=>N output range as follows:

c &= ~(c >> 31);
c -= N;
c &= (c >> 31);
c += N;

After the first line c is in the range 0=>MAXINT with all negative
values mapped to 0.  After the second line c is set up so that all valid
values are in the range -N=>0 and all positive values are overflow
values.  After the third line all values are in the range -N=>0 with the
positive values mapped to 0.  After the fourth line all values are
finally in the range 0=>N...

(Also, I believe it uses the same number of ALU instructions as the
c << 23) >> 31) | c) & ~(c>>31))&0xFF formula...)

   ...jim

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message 

Re: [JAVA2D] What's a trick way to clamp a byte to 255 - 0? -- slowness fixed

2007-08-24 Thread Jim Graham

The premultiplication problem will not be an issue for my little
interpolator since I do not composite.  But it would be for someone
trying to use my interpolator for another purpose than what it was
designed for.


You said that you don't need have the premultiplication problem because
you do not composite, but I wanted to be clear about the terminology
here in case someone else comes across this thread.

The premultiplied form should be used if you have alpha in the images,
whether or not you composite.  After reading your description it sounds
like your images don't have or need alpha since you are simply doing
panoramic stretching of opaque photographs, right?  So, it's really the
lack of an alpha channel which means that the premultiplied issue isn't
applicable here, not the lack of "compositing"...

   ...jim

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


Re: [JAVA2D] How to keep the rasterizer at bay when printing?

2007-08-24 Thread Olivier Lefevre
> I could not find a list the possible values nor an explanation
> of what they do, only a hint that pdl might be a good idea.

It now occurs to me that PDL must stand for Page Description Language,
i.e., just what I wanted but you say it's normally a no-op.

> I don't know what you are driving at [with you remarks on Windows printers]

I am vague on the architecture of Windows printing. I was hoping that in the
case of "real" printers (i.e., with their own rasterizers) applications are
talking directly to the printer driver that is installed with the printer,
not to some generic Windows printer driver. If that's not the case maybe
for high-quaklity printing you are better off generating PostScript and
sending that directly to the printer? A few printers also understand PDF.

> Are you seeing this only when printing a Swing UI? How are you printing?

Yes, I was printing a JPanel with plots in it, i.e., just text ad line art
but with some transparency.

> Are you calling "component.paint(printerGraphics) on the printer graphics.

No I was calling print and I even turned off Swing buffering manually but
I was still getting bitmaps. However now that you told me that print never
rasterizes I went back and I realized the problem is that a sub-widget was
doing its own buffering for performance reasons and I was not turning off
_that_. It seems to work fine now. Thanks!

While we are talkinmg, I have a subsidiary question. When printing or saving
to file the print size is not necessarily what is shown on the screen. One
can simply apply a scaling transform to the graphics object or one can keep
around a private, non-displayable copy of the widget and resize that one
before printing it. The first solution is simpler but are there any gotchas
with rescaling that I am not aware of?

Regards,

-- O.L.

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".


Re: [JAVA2D] How to keep the rasterizer at bay when printing?

2007-08-24 Thread Phil Race

Olivier Lefevre wrote:

I could not find a list the possible values nor an explanation
of what they do, only a hint that pdl might be a good idea.



It now occurs to me that PDL must stand for Page Description Language,
i.e., just what I wanted but you say it's normally a no-op.



I don't know what you are driving at [with you remarks on Windows printers]



I am vague on the architecture of Windows printing. I was hoping that in the
case of "real" printers (i.e., with their own rasterizers) applications are
talking directly to the printer driver that is installed with the printer,
not to some generic Windows printer driver. If that's not the case maybe
for high-quaklity printing you are better off generating PostScript and
sending that directly to the printer? A few printers also understand PDF.



Postscript also doesn't support translucency except in some unlikely and
esoteric implementations
and whilst windows provides a way to see if a printer is a postscript
one it provides no such API for determining
if its a PDF printer.






Are you seeing this only when printing a Swing UI? How are you printing?



Yes, I was printing a JPanel with plots in it, i.e., just text ad line art
but with some transparency.



Are you calling "component.paint(printerGraphics) on the printer graphics.



No I was calling print and I even turned off Swing buffering manually but
I was still getting bitmaps. However now that you told me that print never
rasterizes I went back and I realized the problem is that a sub-widget was
doing its own buffering for performance reasons and I was not turning off
_that_. It seems to work fine now. Thanks!

While we are talkinmg, I have a subsidiary question. When printing or saving
to file the print size is not necessarily what is shown on the screen. One
can simply apply a scaling transform to the graphics object or one can keep
around a private, non-displayable copy of the widget and resize that one
before printing it. The first solution is simpler but are there any gotchas
with rescaling that I am not aware of?




I can't say what you are not aware of until you tell me everything you
are aware of.

Image rescaling will work but be blurry like you complained about to
begin with.
One common mistake is to assume that text scales linearly from screen to
printer.
It doesn't.

If  you scale the graphics 4x then a specific piece of text might scale
by 3.87 or 4.23, or 3.95 , or ..

you can only measure text in the right context. So code that supports
printing of a layed
out component needs to use the screen FontRenderContext for the text.

-phil.

Regards,

-- O.L.




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".