Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 219133 - printer.getDPI() returns 72x72
Summary: printer.getDPI() returns 72x72
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: Macintosh Mac OS X
: P3 normal with 4 votes (vote)
Target Milestone: 3.7 M3   Edit
Assignee: Scott Kovatch CLA
QA Contact: Silenio Quarti CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-02-15 13:28 EST by Karl Hans Kaese-Kassbaum CLA
Modified: 2011-05-17 10:28 EDT (History)
10 users (show)

See Also:


Attachments
test case to demonstrate different line thicknesses (1.86 KB, text/x-java)
2008-04-12 10:25 EDT, Karl Hans Kaese-Kassbaum CLA
no flags Details
printing patch (3.39 KB, text/plain)
2010-02-25 15:22 EST, Chris Russo CLA
john.arthorne: iplog+
Details
Cocoa fix (8.77 KB, patch)
2010-10-20 19:29 EDT, Scott Kovatch CLA
no flags Details | Diff
Snap of debug session showing destType = 65536... strange (372.91 KB, image/png)
2010-10-21 14:51 EDT, Carolyn MacLeod CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Karl Hans Kaese-Kassbaum CLA 2008-02-15 13:28:20 EST
I am using Leopard on an Intel Mac (mini) and SWT 3.4M5 for carbon. When I 
query the printer resolution with printer.getDPI() I always get 72x72 
although the real resolution is 600x600.
 I know there was (or still is) a corresponding problem with linux gtk.
 The printer driver used is Gutenprint 5.1.3. The printer is a network printer (HPLJ6L).
Comment 1 Karl Hans Kaese-Kassbaum CLA 2008-02-19 12:32:59 EST
Printing to the same printer from OpenOffice 2.3.1 (Mac OS Leopard) shows, that graphics output can be produced with high resolution. Printing graphics from programms using SWT you get very broad lines, which is not acceptable.
Comment 2 Kevin Barnes CLA 2008-02-29 00:56:24 EST
PMGetResolution is always returning 72x72. On 10.5 sometimes returns the correct dpi, but there does not seem to be a Tiger equivalent to that function.
Comment 3 Kevin Barnes CLA 2008-02-29 00:59:04 EST
oops... second sentence should have been:
On 10.5, PMPrinterGetOutputResolution sometimes returns the
correct dpi, but there does not seem to be a Tiger equivalent to that function.
Comment 4 Kevin Barnes CLA 2008-04-11 16:44:41 EDT
How are you printing your lines? I changed the implementation of getDPI locally and printed squares which I expected to be 1" on each side. It looks to me that 72x72 gives the correct result.
Please attach a test case that demonstrates the bug.
Comment 5 Karl Hans Kaese-Kassbaum CLA 2008-04-12 10:25:50 EDT
Created attachment 95808 [details]
test case to demonstrate different line thicknesses
Comment 6 Kevin Barnes CLA 2008-04-16 11:40:03 EDT
fixed > 20080416
Comment 7 Silenio Quarti CLA 2008-06-10 16:22:17 EDT
The fix for this bug has been removed because of bug#236419. We will rework the changes after 3.4 ships.
Comment 8 Chris Russo CLA 2008-07-11 00:34:32 EDT
This bug is the one show-stopper that's keeping me from releasing my application.  If there is a workaround or advice for creating even a bit of a hacked fix, that would be much appreciated.  Thanks.
Comment 9 Steve Northover CLA 2008-07-17 17:46:15 EDT
> We will rework the changes after 3.4 ships.

We need to take a quick look at this again.  Chris is stuck and can't wait for cocoa.
Comment 10 Silenio Quarti CLA 2008-07-23 12:07:39 EDT
We have fixed the issues that caused bug#236419. Please get the latest SWT (either from HEAD or the next integration build) and try it out. Report any issues that you find as soon as possible. We considering putting this change in 3.4.x.
Comment 11 Chris Russo CLA 2008-09-01 20:02:43 EDT
This issue wasn't caused or all that closely related to bug#236419.  Fixing this issue was going to involve some extensive work supporting newer Mac printing calls.

I just grabbed the latest SWT source from HEAD then tried printing with my application as well as the test case attached to this bug.  Both showed that Macintosh printing is still off.  The resolution for the printer when I use my application shows 600x600 DPI and prints out at an obviously much higher resolution.

On the Mac, the resolution continues to show 72x72 (and I've played with the image quality settings in the Mac print preferences) then prints out in big thick lines that I can only assume are 72 DPI.

Comment 12 Chris Russo CLA 2008-09-01 20:04:11 EDT
I'd like to request that this bug be reopened based upon the tests that I did that confirmed that this issue isn't fixed.  --thanks
Comment 13 Silenio Quarti CLA 2008-09-03 11:49:37 EDT
What is the driver for your printer? Generic PostScript Printer? This one will always be 72x72. I installed my printer using a specific driver for it (IBM Infoprint 1552) and that gave me another tab in the printer dialog to select the desired resolution. Printer.getDPI() returns the correct resolution for me in that case. Please could you confirm your driver?

Comment 14 Chris Russo CLA 2008-09-05 12:31:40 EDT
It's a Canon IP1800.

Besides the dpi reporting incorrectly, it's also worth noting that the test case attached to this bug prints out with thick lines for me.  Is it working correctly for you?
Comment 15 Carolyn MacLeod CLA 2008-09-05 13:21:33 EDT
KH & McQ, Does either of you have access to a non-IBM printer that you can print to from your Mac? We can't replicate this problem here. If you do, can you please run the snippet in comment 5, and let us know what you see? Thanks!
Comment 16 Silenio Quarti CLA 2008-09-05 13:38:47 EDT
For me, it reports the right res and the lines are not thick. Note that if it reports 72x72 dpi, it will have thick lines.
Comment 17 Mike Wilson CLA 2008-09-16 16:19:02 EDT
I've got 2 HP printers at home. I'll try them this weekend and report the results.
Comment 18 Mike Wilson CLA 2008-09-29 08:47:20 EDT
Bah. Just found this bug again. I never got around to trying it. :-(

Comment 19 Chris Russo CLA 2008-10-08 21:46:51 EDT
I spent a little time trying to debug this tonight.  During the Printer.getDPI() call, there's a call to OS.PMPrinterGetOutputResolution() that's made to actually get the resolution.  No error is checked on it, so I added some error printing and saw that the call returns a kPMKeyNotFound error.

I wasn't able to figure out what that really means in this context.

On a related note, I had better luck using the PMPrinterGetIndexedPrinterResultion() call to find the best printer resolution when playing around with the Mac API in C++.  Since that call and the one that gets the printer resolution count don't seem to have hooks yet, I wasn't able to test it out in my Java app.  Might be a clue for someone with the ability to add those calls to the jnilib.

Comment 20 Carolyn MacLeod CLA 2008-10-09 01:35:28 EDT
Nice work, Chris - very interesting.

The doc for PMPrinterGetOutputResolution says it will return an error "if the resolution cannot be reliably determined", so my guess is that that's what kPMKeyNotFound means. (It seems to have something to do with Ticket Services and Printing Dialog Extensions and Printer Modules... http://developer.apple.com/documentation/Printing/Reference/TicketServices_Ref/Reference/reference.html)

What count does PMPrinterGetPrinterResolutionCount return for your printer?
And what index did you pass in to PMPrinterGetIndexedPrinterResolution?
Did you look at the resolutions at other indices?

FYI, here's how to add new natives to the SWT JNI libraries: http://www.eclipse.org/swt/jnigen.php

Hmm... here's an Apple mailing list post where someone mentions a similar problem, except it is with PMPrinterGetIndexedPrinterResolution: http://lists.apple.com/archives/printing/2008/Feb/msg00057.html

Scott, how well do you know Core Printing? I suppose we could try using PMPrinterGetOutputResolution first (it is preferred, because it takes the user's print settings into account), and if it returns an error then call PMPrinterGetPrinterResolutionCount, and if that returns a valid count, then call PMPrinterGetIndexedPrinterResolution (maybe using index for highest resolution?).

What I don't understand is why Chris' PMPrinterGetOutputResolution is failing - it almost seems like the Printer Module is bogus somehow.
Comment 21 Scott Kovatch CLA 2008-10-09 12:38:45 EDT
Mike Swingler was the printing guy -- I'm not terribly familiar with printing. I'm adding Mike to the CC list.
Comment 22 Mike Swingler CLA 2008-10-09 12:49:43 EDT
I understand printing as it is implemented on the AWT side, which simply uses Quartz primitives and strokes lines in a 72 DPI coordinate space that is mapped to the native resolution or stored abstractly (like PostScript). We don't actually pay attention to the printer's advertised resolution, because it's so often wrong. 

I'd recommend posting a question to the printing@lists.apple.com list. Sorry.
Comment 23 Karl Hans Kaese-Kassbaum CLA 2008-12-05 08:59:27 EST
I tested the new cocoa-version of swt (3.5M3) on Mac Leopard and I am disappointed. This bug has not been resolved.
Comment 24 Silenio Quarti CLA 2008-12-05 10:37:05 EST
Yes, Printer.getDPI() is not implemented in cocoa. I could not find any cocoa API to get the printer resolution. I believe the only way is to use CorePrinting function PMPrinterGetOutputResolution(). For that, we need a printer session and a printer settings. The later is easy to get from cocoa. I have not found any simple way to get the former.

The goods news is once getDPI() is implemented all the other supporting code is already in place.
Comment 25 Antti Kalliokoski CLA 2009-06-26 13:18:40 EDT
Using Core Printing obtaining printer DPI is quite simple:
Fist Call PMPrinterGetPrinterResolutionCount(printer,numOfResolutions) and then go though to loop PMPrinterGetIndexedPrinterResolution(printer, resolution index, resolution struct). 

I have tested this with Samsung CLP-315 and two different Xerox network printers.

Is there some problem that I can't see?
Comment 26 Silenio Quarti CLA 2009-06-29 09:22:35 EDT
Which index is the current resolution? The carbon code looks like this in HEAD (ie. we use PMPrinterGetOutputResolution()).



PMResolution resolution = new PMResolution();
if (OS.VERSION >= 0x1050) {
	int[] printer = new int[1]; 
	OS.PMSessionGetCurrentPrinter(printSession, printer);
	OS.PMPrinterGetOutputResolution(printer[0], printSettings, resolution);
}
if (resolution.hRes == 0 || resolution.vRes == 0) {
	OS.PMGetResolution(pageFormat, resolution);
}
return new Point((int)resolution.hRes, (int)resolution.vRes);
Comment 27 Antti Kalliokoski CLA 2009-07-01 03:34:22 EDT
In Cocoa/ Core Printing

PMPrinterGetIndexedPrinterResolution
Can't give currently used printer resolution, but it's good choice in those situation where PMPrinterGetOutputResolution fails. There is couple things to note when using PMPrinterGetOutputResolution (hopefully this is not too basic information)

1. It works only 10.5
2. It can called only after print dialog is closed and 
(there is also small misunderstanding in print dialog (NSPrintPanel) handling it's not a bug that it starts printing even if user clicks preview). It's only different print destination type 
3. Check that destination type is printer and it's resolution

if (PMSessionGetDestinationType(printer, printSettings, *desType)==noErr) {
   if (desType==kPMDestinationPrinter) {
if (PMPrinterGetOutputResolution(printer,printSettings, *resolution)!=noErr) {
if (PMPrinterGetPrinterResolutionCount==noErr)
PMPrinterGetIndexedPrinterResolution // go select best resolution
else
if (PMPrinterGetIndexedPrinterResolution(printer,1,*resolution)==noErr
//printer has only one supported resolution
else
//put resolution to 300*300, because there is no printers which can't handle that

}


}

}
elseif {desType==kPMDestinationPreview) {
Start Preview app e.g. using NSURL
}
}
Not all drivers support the PMPrinterGetOutputResolution function, but using it when possible I think and using best possible in other cases then I think that we would get useful printing for Mac OS X too
Comment 28 Antti Kalliokoski CLA 2009-07-03 06:24:00 EDT
Here is working Cocoa/Core printing code:
 
	NSPrintInfo* info = [NSPrintInfo sharedPrintInfo];
	PMPrintSession pmPrintSession = [info PMPrintSession];
	PMPrinter printer;
	OSStatus err = PMSessionGetCurrentPrinter(pmPrintSession,&printer);
	if (err == noErr) {
		PMPrintSettings printSettings = [info PMPrintSettings];
		PMDestinationType desType;
		if (PMSessionGetDestinationType(pmPrintSession, printSettings, &desType)==noErr) {
			if (desType==kPMDestinationPrinter) {
				PMResolution resolution;
				if (PMPrinterGetOutputResolution(printer,printSettings, &resolution)!=noErr) {
					UInt32 numberOfResolutions=0;
					if (PMPrinterGetPrinterResolutionCount(printer,&numberOfResolutions)==noErr){
						int i=0;
						PMResolution tempResolution;
						tempResolution.vRes=0;
						tempResolution.hRes=0;
						for (i=0;i<(int)numberOfResolutions;i++) {
							if (PMPrinterGetIndexedPrinterResolution(printer,numberOfResolutions,&resolution)==noErr) {
								if (resolution.vRes > tempResolution.vRes && resolution.hRes > tempResolution.hRes) {
									tempResolution=resolution;
								}
								
								
							}
							else {
								resolution.vRes=300.00;
								resolution.hRes=300.00;
								return resolution;
							}
						}
						return tempResolution;
					}

				}
				else {
					return resolution;
				}

			}
		}

	}
	PMResolution defaltResoluiton;
	defaltResoluiton.vRes=72;
	defaltResoluiton.hRes=72;
	return defaltResoluiton;
Comment 29 Chris Russo CLA 2010-01-27 16:33:07 EST
I just loaded the latest cocoa swt from CVS as of today to try out the test code attached to this bug, and this is still not working.  Instead of pulling the printer resolution, the Device getDPI() calls getScreeenDPI() which returns 72x72.  The print size is incorrect, drawing lines of inappropriate width.

Interestingly enough, I linked against the carbon swt in Eclipse 3.5.1 and it showed a 600x600 DPI, which is what I would have expected in the first place.  The lines drawn with that library look to be the correct size.
Comment 30 Chris Russo CLA 2010-02-25 15:22:45 EST
Created attachment 160236 [details]
printing patch

I now have a solution to this problem in my own code.

I took the objective-c snippet from comment #28 by Antti, reworked it into Java and put it into place in Printer.java for getDPI() Carbon.  I also needed to add the OS.java calls for PMPrinterGetPrinterResolutionCount() and PMPrinterGetIndexedPrinterResolution() then followed the documented process to generate and compile the glue code/lib.

I've attached the relevant portion of a cvs diff of OS.java and Printer.java to this bug.

This bug seriously impacts someone wanting to print out at resolutions better than 72DPI on OSX.  Please consider addressing it in a very near release.

As I mentioned previously, this problem also impacts Cocoa.  The Cocoa getDPI() call is equally flawed but could be fixed with basically the same code.
Comment 31 Scott Kovatch CLA 2010-10-20 19:29:28 EDT
Created attachment 181347 [details]
Cocoa fix

Based on the code in comment #28, I put together this patch to Printer.getDPI(). With this change I get the same print behavior as Windows 7. Once you get the PMPrintSession and PMPrintSettings from the NSPrintInfo you can just use the CorePrinting code we had in Carbon with the addition of the check for additional resolutions.
Comment 32 Carolyn MacLeod CLA 2010-10-21 13:03:51 EDT
Scott, can you please attach os_custom.h? I had to re-create it. I assume all of the new calls are in carbon lib?

#define PMPrinterGetIndexedPrinterResolution_LIB "com.apple.Carbon"
#define PMPrinterGetOutputResolution_LIB "com.apple.Carbon"
#define PMPrinterGetPrinterResolutionCount_LIB "com.apple.Carbon"
#define PMSessionGetCurrentPrinter_LIB "com.apple.Carbon"
#define PMSessionGetDestinationType_LIB "com.apple.Carbon"
#define PMPrinterGetIndexedPrinterResolution_LIB "com.apple.Carbon"
#define PMPrinterGetOutputResolution_LIB "com.apple.Carbon"
#define PMPrinterGetPrinterResolutionCount_LIB "com.apple.Carbon"
#define PMSessionGetCurrentPrinter_LIB "com.apple.Carbon"
#define PMSessionGetDestinationType_LIB "com.apple.Carbon"
Comment 33 Scott Kovatch CLA 2010-10-21 13:17:24 EDT
(In reply to comment #32)
> Scott, can you please attach os_custom.h? I had to re-create it. I assume all
> of the new calls are in carbon lib?

Oops -- sorry. No, they're in ApplicationServices.

#define PMSessionGetCurrentPrinter_LIB "com.apple.ApplicationServices"
#define PMSessionGetDestinationType_LIB "com.apple.ApplicationServices"
#define PMPrinterGetPrinterResolutionCount_LIB "com.apple.ApplicationServices"
#define PMPrinterGetOutputResolution_LIB "com.apple.ApplicationServices"
#define PMPrinterGetIndexedPrinterResolution_LIB "com.apple.ApplicationServices"
Comment 34 Carolyn MacLeod CLA 2010-10-21 14:51:15 EDT
Created attachment 181433 [details]
Snap of debug session showing destType = 65536... strange

Thanks. Funny, those methods seem to be in com.apple.Carbon also... it linked ok, and seemed to run about the same...

Anyhow, I recompiled with com.apple.ApplicationServices (and high hopes <g>), but I am still getting a strange value back from PMSessionGetDestinationType. The destType is 65536 (0x10000). This isn't even in the same ballpark as the expected destTypes (0 to 4).

So the end result is that I am still getting a DPI of 72 x 72.

Any ideas? I am running OS X 10.5.8 on a PowerPC G5 Mac.

I googled, and got this vaguely similar-sounding hit, but it's ancient...
http://lists.apple.com/archives/Carbon-development/2002/Feb/msg00345.html
I wonder if something similar happened with my version of CarbonLib (or ApplicationServicesLib <g>).
How can I tell what version of the libs I have?
Comment 35 Scott Kovatch CLA 2010-10-21 15:15:05 EDT
(In reply to comment #34)

> Anyhow, I recompiled with com.apple.ApplicationServices (and high hopes <g>),
> but I am still getting a strange value back from PMSessionGetDestinationType.
> The destType is 65536 (0x10000). This isn't even in the same ballpark as the
> expected destTypes (0 to 4).
> 
> So the end result is that I am still getting a DPI of 72 x 72.
> 
> Any ideas? I am running OS X 10.5.8 on a PowerPC G5 Mac.

PMSessionGetDestinationType returns a PMDestinationType, which is typedef'd to UInt16. Try changing that int[] to a short[] and see if it's better. The fix still works for me with that change.
Comment 36 Carolyn MacLeod CLA 2010-10-22 09:44:11 EDT
(In reply to comment #34)

As soon as I saw your comment, I knew that would work <g>.
It is now tested, and it looks great. Nice thin lines, correct DPI, and all of my line measurement tests are good, too. Fonts are still looking fine.

Code looks good - go ahead and commit. Please remember to commit the .c & .h stuff, too <grin>.
Also, please double check the param types for the other new methods (PMPrinterGetOutputResolution, PMPrinterGetPrinterResolutionCount, PMPrinterGetIndexedPrinterResolution) to make sure there are no other shorts. I couldn't test those calls because PMPrinterGetOutputResolution returns noErr. (which is good).   :)

The only other comment I have - and I am not sure that it is a problem - is that getDPI is called a bunch of times in the printing methods, and I wonder if there's a nice safe way to cache the info.
I would go ahead and commit this first before thinking about caching. It's probably not important because it's only a few OS calls each time.

Thanks, Scott! I am going to commit the GTK fix for this same problem (bug 150870) later today.  :)

And a big thanks to Antti and Chris, too, for providing patches to help get this fixed.
Comment 37 Scott Kovatch CLA 2010-10-22 13:05:59 EDT
(In reply to comment #36)

> Also, please double check the param types for the other new methods
> (PMPrinterGetOutputResolution, PMPrinterGetPrinterResolutionCount,
> PMPrinterGetIndexedPrinterResolution) to make sure there are no other shorts. I
> couldn't test those calls because PMPrinterGetOutputResolution returns noErr.
> (which is good).   :)

Everything else is either UInt32 or a pointer, so we're set there.

> The only other comment I have - and I am not sure that it is a problem - is
> that getDPI is called a bunch of times in the printing methods, and I wonder if
> there's a nice safe way to cache the info.
> I would go ahead and commit this first before thinking about caching. It's
> probably not important because it's only a few OS calls each time.

It does seem like we should be able to store the data as it won't change for each print job, but I'm also not sure it's worth the effort since it doesn't appear to be expensive to get the data.

Fixed in Cocoa only > 20101022.