Quartz and user space

Discussion in 'Mac Programming' started by MarkHamilton, Jun 26, 2005.

  1. MarkHamilton macrumors newbie

    Joined:
    Jun 21, 2005
    Location:
    Albuquerque, NM, USA
    #1
    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
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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.
     
  3. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #3
    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.
     

    Attached Files:

  4. MarkHamilton thread starter macrumors newbie

    Joined:
    Jun 21, 2005
    Location:
    Albuquerque, NM, USA
    #4
    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?
     
  5. MarkHamilton thread starter macrumors newbie

    Joined:
    Jun 21, 2005
    Location:
    Albuquerque, NM, USA
    #5
    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.
     
  6. MarkHamilton thread starter macrumors newbie

    Joined:
    Jun 21, 2005
    Location:
    Albuquerque, NM, USA
    #7
    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.
     
  7. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    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.
     
  8. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #9
    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.
     
  9. MarkHamilton thread starter macrumors newbie

    Joined:
    Jun 21, 2005
    Location:
    Albuquerque, NM, USA
    #10
    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.
     
  10. devman macrumors 65816

    devman

    Joined:
    Apr 19, 2004
    Location:
    AU
    #11
    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.
     
  11. devman macrumors 65816

    devman

    Joined:
    Apr 19, 2004
    Location:
    AU
    #12
    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).
     
  12. GeeYouEye macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
    #13
    Very good point.

    I could be wrong, but IIRC, the 14" iBook uses a 72 dpi screen, as do TiBooks and iBooks rev A-C (clamshell).
     

Share This Page