Cocoa text rendering and setUsesScreenFonts: ATSUI? QuickDraw? Something else?

  • I'm trying to write some code which uses low level ATSUI calls to draw
    text. Unfortunately, the output isn't quite what I desire.
    Specifically, I'm hoping to mimic the rendering done by Cocoa apps. I'm
    using Hydra as an example here, because it provides a check-box "Use
    screen fonts" which makes what I'm seeing quite clear:

    If you download Hydra, it defaults to displaying text using 10 point
    Monaco, just like Project Builder. This text is not antialiased when it
    is drawn to the screen, also like Project Builder and any other Mac OS
    X application (Safari, Mail, whatever). However, if you open "Hydra ->
    Preferences", you can toggle a box which reads "Use screen fonts". I'm
    assuming that this turns around and calls [NSLayoutManager
    setUsesScreenFonts]. If I uncheck this box, I get identical (or almost
    identical) rendering as my ATSUI calls: 10 point Monaco text that is
    being antialiased. So my question is:

    What does [NSLayoutManager setUsesScreenFonts] do to get "screen
    fonts"? Does it change the ATSUI drawing settings? Does it draw with
    QuickDraw instead of Quartz? Is it actually selecting alternate fonts
    using ATS? It is in cases like this that I wish Apple would release the
    code for Cocoa, so I could answer this question myself.

    My application is drawing text like this:

    1. Create an ATSUStyle object.
    2. Set the text size ( X2Fix( 10 ) )
    3. Set the font ( Using ATSUFindFontFromName on the string "Monaco" )
    4. Create an ATSUTextLayout object.
    5. Add a CGContextRef to the object (I'm using Quartz).
    5. Add my text to the object.
    6. Add the style to the object.
    7. Draw the text.

    I have tried the following settings:

    1. Forcing antialiasing off. This gives me correct (?) rendering at 10
    points, but much worse rendering at higher sizes. At higher sizes,
    Cocoa apps antialias the text.
    2. Using ATSUI options such as kATSLineUseDeviceMetrics and
    kATSLineFractDisable. This doesn't seem to affect anything.

    I've learned through searching the mailing list archives that Mac OS X
    does not support bitmap fonts, but that doesn't appear to be the issue
    here, since Cocoa is doing the right thing.

    Thank you for your assistance,

    Evan Jones

    --
    Evan Jones: http://www.eng.uwaterloo.ca/~ejones/
    "Computers are useless. They can only give answers" - Pablo Picasso
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Wednesday, April 9, 2003, at 5:34 PM, Evan Jones wrote:

    > What does [NSLayoutManager setUsesScreenFonts] do to get "screen
    > fonts"? Does it change the ATSUI drawing settings? Does it draw with
    > QuickDraw instead of Quartz? Is it actually selecting alternate fonts
    > using ATS? It is in cases like this that I wish Apple would release
    > the code for Cocoa, so I could answer this question myself.

    It selects alternate fonts, using the -[NSFont screenFont] method.

    Douglas Davidson
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Thursday, Apr 10, 2003, at 14:36 US/Eastern, Douglas Davidson wrote:
    >> What does [NSLayoutManager setUsesScreenFonts] do to get "screen
    >> fonts"? Does it change the ATSUI drawing settings? Does it draw with
    >> QuickDraw instead of Quartz? Is it actually selecting alternate fonts
    >> using ATS? It is in cases like this that I wish Apple would release
    >> the code for Cocoa, so I could answer this question myself.
    > It selects alternate fonts, using the -[NSFont screenFont] method.

    Okay, that makes sense. Unfortunately, it doesn't seem that is the
    entire answer. I tested a quick hack below to use this Cocoa class to
    find my font which I then draw with using ATSUI. It doesn't appear to
    be the answer to my problem.

    ATSUFindFontFromName( "Monaco", 6, kFontFullName, (unsigned)
    kFontNoPlatform, kFontRomanScript, (unsigned) kFontNoLanguage, &fontid
    );

    NSString* fontName = @"Monaco";
    NSFont* font = [NSFont fontWithName: fontName size: 10];
    assert( font != nil );

    NSFont* screenFont = [font screenFont];
    assert( screenFont != nil );

    // When I execute this line, my font id and the NSFont's font id have
    the same value
    // I found this private _atsFontID method using RuntimeBrowser
    // When I use ATSUI to draw with this font, I get the same output as
    before: Antialiased
    // Monaco 10, instead of Project Builder's nice un-antialiased Monaco
    10.
    fprintf( stderr, "My id = %p NSFont's id = %p\n", fontid, [screenFont
    _atsFontID] );
    fontid = [screenFont _atsFontID];

    So my question is still: What does this class do, or does Cocoa's text
    rendering system do, to get "screen fonts". There was a mention of this
    issue in David Hyatt's weblog (Safari development) that sheds some
    light on this issue:

    http://www.mozillazine.org/weblogs/hyatt/archives/2003_03.html

    (1) Safari *is* using the wrong fonts for rendering to the screen.
    Because of our use of lower-level APIs, we missed out on a font
    substitution step that happens when rendering to the screen where the
    bitmap font ends up getting chosen for rendering.  This is a bug in
    Safari, and we're looking into fixing it.

    (2) The global OS AA setting is not being obeyed.

    (3) Above and beyond the OS AA setting, AppKit also has hardcoded rules
    at a higher level, e.g., don't AA Courier or Monaco.  Again we are
    missing these hardcoded rules.

    My problem appears to be exactly the same, as I am doing the same
    thing: Using the lower level ATSUI APIs for drawing Unicode strings.
    I'm not surprised about #3. But interestingly, it doesn't ALWAYS turn
    off antialiasing: Only for Monaco at 10 points or less. If you make it
    12 points, it is AAed again, and looks the same (more or less) as my
    text. So I would say that Apple needs to expose these hard coded rules
    to ATSUI/Carbon somehow, to provide a consistent user experience.

    And then later:

    We have successfully switched to selecting the appropriate fonts when
    rendering to the screen (vs. rendering to a printer).  Safari still
    antialiases everything, but at least the same fonts are being chosen as
    with other Cocoa apps that use AppKit.

    So what was this fix? It would be nice to know, if possible. Maybe I'll
    email him, and see if he can tell me. At any rate, I've wasted FAR too
    much time on this now. I'm going to live with antialiased text, even if
    in some cases it isn't as nice.

    Thanks for your assistance.

    --
    Evan Jones: http://www.eng.uwaterloo.ca/~ejones/
    "Computers are useless. They can only give answers" - Pablo Picasso
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
previous month april 2003 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
Go to today