Community
Participate
Working Groups
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).
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.
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.
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.
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.
Created attachment 95808 [details] test case to demonstrate different line thicknesses
fixed > 20080416
The fix for this bug has been removed because of bug#236419. We will rework the changes after 3.4 ships.
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.
> 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.
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.
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.
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
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?
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?
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!
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.
I've got 2 HP printers at home. I'll try them this weekend and report the results.
Bah. Just found this bug again. I never got around to trying it. :-(
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.
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.
Mike Swingler was the printing guy -- I'm not terribly familiar with printing. I'm adding Mike to the CC list.
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.
I tested the new cocoa-version of swt (3.5M3) on Mac Leopard and I am disappointed. This bug has not been resolved.
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.
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?
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);
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
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;
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.
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.
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.
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"
(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"
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?
(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.
(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.
(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.