Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

MarkHamilton

macrumors newbie
Original poster
Jun 21, 2005
12
0
Albuquerque, NM, USA
Hi,

I have a question about the Quartz user coordinate system. The Apple documentation indicates that the CTM handles the transformation from user space to device space. (In at least one document it says that no math is required.) However, I can't find any information or examples showing how you specify the units to Quartz.

Let's suppose that I want draw a 1.5" x 1.5" square on my output device (window or page.) How does Quartz know that the units in the CGContextAddRect call are inches and not feet, yards, or light-years? (Or millimeters, for that matter.)

If I need to add my own scaling to the CTM, how do I determine the resolution and the units for the output device? I've looked at a number of the example apps, and they all seem to draw their shapes in pixels.

I suspect that I'm just not reading the correct document or examples. If someone could point me to the right ones I'd apreciate the help.

Thanks.

Mark E. Hamilton
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Quartz (at the moment) works with 72dpi (for drawing to the screen). So if you want a 1" square it should be 72 pixels square (I think). If you render this to the printer it will still be 1 inch square but quartz calls will probably render with greater detail (as the printer should be greater than 72dpi). Quartz handels this automatically.

Note that the resolution independant support works the same way: your app assumes it's drawing to 72dpi and the output is scaled by quartz. I'll post some nice results I've been getting with a custom control that draws Aqua style "blobs" and the way they scale for free when I get home.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
OK so here we go. On the bottom is the app at a UI scaling of 1.0 (i.e. normal). On the top is at 3.0. The code does not know what size it is drawing at. As you can see the level of detail is much higher at the 3.0 scaling. Note that the reason this scales so well (as opposed to the standard UI elements at the moment) is that it does not use any bitmaps at all. It's all drawn with Quartz.
 

Attachments

  • scaling10.png
    scaling10.png
    6.4 KB · Views: 569
  • scaling30.png
    scaling30.png
    19 KB · Views: 374

MarkHamilton

macrumors newbie
Original poster
Jun 21, 2005
12
0
Albuquerque, NM, USA
I re-wrote a simple drawing example to scale to 72dpi and drew a 1x1 square.

CGContextScaleCTM(myContext, 72.0, 72.0 );
CGContextFillRect (myContext, CGRectMake(0, 0, 1.0, 1.0 ));

Measuring it on the screen of my 20" Cinema Display it's only about 11/16, which implies that the screen resolution is actually 100 dpi. I upped my scale factor to that and the square is now 1" on the screen.

However, this is not device independence if I have to know the resolution of the output device in order to scale my output correctly. I don't have a simple printing example just yet (that's actually what I've been trying to figure out); will the same scale factor of 100 produce a 1" square on the paper? For any of the printers I've got?

If not how do I query the resolution of the output device before I draw?
 

MarkHamilton

macrumors newbie
Original poster
Jun 21, 2005
12
0
Albuquerque, NM, USA
I plugged in the necessary print functions and printed the square at a scale factor of 100 to the printer. It was about 1 3/8", which translates to 72dpi. Again changing the scale factor to that in the drawing code produced a 1" square on the output device (paper this time.)

So, I guess I don't understand how to use the device independence features of Quartz, if I have to know the resolution of my output device in order to scale my drawing correctly. Any guidance or pointers would be greatlly appreciated. Thanks.
 

MarkHamilton

macrumors newbie
Original poster
Jun 21, 2005
12
0
Albuquerque, NM, USA
Thanks, Robbie. That seems to work. It sure is complicated, though, especially since the left out a critical include file in the example. I managed to track it down in the IOKit.

You'd think they'd make getting the resolution an API call, similar to the PMResolution() call for printers.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
MarkHamilton said:
Thanks, Robbie. That seems to work. It sure is complicated, though, especially since the left out a critical include file in the example. I managed to track it down in the IOKit.

You'd think they'd make getting the resolution an API call, similar to the PMResolution() call for printers.

I was honestly quite surprised when my search turned that up. I was expecting that there would be a method on graphics context to get the DPI of the context.
 

Sayer

macrumors 6502a
Jan 4, 2002
981
0
Austin, TX
You should never make assumptions about the environment your software is running in, especially in graphics contexts.

The current crop of Macs can run displays at a variety of resolutions and I don't think any of them have a straight 72 DPI resolution anymore. All LCDs are 100 DPI-plus. I remember reading somewhere that Apple found 100 DPI to be a "sweet-spot" for their LCD screens and so they start there and go up.

Also if you are measuring your screen image, again the DPI of the output device will vary naturally as Quartz renders a 72 DPI image to whatever screen resolution you are currently using.

The only place you should really worry about 72 DPI = 1 inch is the printer or when saving to PDF (which is actually the intermediate step between the application's rendering and the printed output of a printer).

If every drawing app was 1:1 ratio we'd need screens the size of entire walls to work on large images. Okay, the automakers do use wall-sized displays for 1:1 display to verify/tweak designs but that is not the "norm" anywhere in any industry.
 

MarkHamilton

macrumors newbie
Original poster
Jun 21, 2005
12
0
Albuquerque, NM, USA
Sayer said:
You should never make assumptions about the environment your software is running in, especially in graphics contexts.

The current crop of Macs can run displays at a variety of resolutions and I don't think any of them have a straight 72 DPI resolution anymore. All LCDs are 100 DPI-plus. I remember reading somewhere that Apple found 100 DPI to be a "sweet-spot" for their LCD screens and so they start there and go up.

Also if you are measuring your screen image, again the DPI of the output device will vary naturally as Quartz renders a 72 DPI image to whatever screen resolution you are currently using.

If every drawing app was 1:1 ratio we'd need screens the size of entire walls to work on large images. Okay, the automakers do use wall-sized displays for 1:1 display to verify/tweak designs but that is not the "norm" anywhere in any industry.

Thanks, Sayer. I was trying to not make any assumptions, which was the reason for my question. What I really wanted to do was to ensure that the patterns I'm trying to print come out the size I need them. I guess I was expecting, like Robbie, that there would be some simple way to get it from the graphics context. The only reason that I was measuring the screen was that it is a quick way to ensure that my transforms are set up correctly. (I wouldn't mind one of those wall-size screens, though. :) )

I guess my whole point was that Apple claims that Quartz is device independent, and it's not. The way that I look at it from an API perspective is that the application should be able to specify that the user-space units are pixels, millimeters, inches, or whatever, and the underlying code should apply the necessary transformations, regardless of what the actual output device is, to produce the requested output. As it is, if you need something to be a particular size on the output device, you have to know specific details about it and add the scaling to the CTM yourself.
 

devman

macrumors 65816
Apr 19, 2004
1,242
8
AU
from CGDisplayConfiguration.h (10.3 and later only)

CGSize CGDisplayScreenSize(CGDirectDisplayID display)

I believe this and the referenced IOKit code simply return whatever the EDID data in the display ROM says.

You can use CGGetActiveDisplayList and/or CGMainDisplayID to get the display ID.

note: I've not tried the above.
 

devman

macrumors 65816
Apr 19, 2004
1,242
8
AU
Hmm, I just trawled the docs and it seems there are Cocoa level APIs related to this.

Both NSScreen and NSWindow have a method deviceDescription that returns an NSDictionary. The key NSDeviceResolution returns a NSValue that contains an NSSize that indicates the device resolution in DPI * the userSpaceScaleFactor (for resolution independent ui).
 

GeeYouEye

macrumors 68000
Dec 9, 2001
1,669
10
State of Denial
Sayer said:
You should never make assumptions about the environment your software is running in, especially in graphics contexts.
Very good point.

The current crop of Macs can run displays at a variety of resolutions and I don't think any of them have a straight 72 DPI resolution anymore. All LCDs are 100 DPI-plus. I remember reading somewhere that Apple found 100 DPI to be a "sweet-spot" for their LCD screens and so they start there and go up.

I could be wrong, but IIRC, the 14" iBook uses a 72 dpi screen, as do TiBooks and iBooks rev A-C (clamshell).
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.