I am trying to understand how Cocoa's text drawing system positions text
on OS X.

I have setup some text attributes as follows:

    let emojiFont   = NSFont.systemFontOfSize( 18 )
    let emojiStyle  =
NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as!
NSMutableParagraphStyle

    self.emojiAttributes[ NSFontAttributeName ]             = emojiFont
    self.emojiAttributes[ NSParagraphStyleAttributeName]    = emojiStyle

The drawing code looks like:

    let kSquareSize = CGFloat( 50 )

    let nRows           = 1
    let nColumns        = 1
    let nBins           = nRows * nColumns
    let binImageFrame   = NSMakeRect( 0, 0, CGFloat(nBins) *
self.kSquareSize, self.kSquareSize )

    let binImage    = NSBitmapImageRep.init( bitmapDataPlanes:  nil,
        pixelsWide:        Int(NSWidth( binImageFrame )),
        pixelsHigh:        Int(NSHeight( binImageFrame )),
        bitsPerSample:     8,
        samplesPerPixel:   4,
        hasAlpha:          true,
        isPlanar:          false,
        colorSpaceName:    NSDeviceRGBColorSpace,
        bytesPerRow:       0,
        bitsPerPixel:      0 )!

    let binContext  = NSGraphicsContext.init( bitmapImageRep: binImage )!

    NSGraphicsContext.saveGraphicsState()
    NSGraphicsContext.setCurrentContext( binContext )

    //
    // Draw
    //
    NSColor.lightGrayColor().setFill()
    NSRectFill( binImageFrame )

    let coordinates  = NSMakeRect( 0, 0, kSquareSize, kSquareSize )

    self.drawEmoji( 0, coordinates: coordinates )

    //
    // Close Out
    //
    NSGraphicsContext.restoreGraphicsState()

    let emojiImage = NSImage.init( size: binImageFrame.size )

    emojiImage.addRepresentation( binImage )

    //
    // Save
    //
    let imageData: NSData = emojiImage.TIFFRepresentation!

    imageData.writeToFile( "/Users/eric/Desktop/bin.tiff", atomically: true )

and the drawEmoji function is:

    func drawEmoji( emojiIndex: Int, coordinates: NSRect )
    {
        NSRectFill( coordinates )

        let textStorage     = NSTextStorage.init( string: "😁",
attributes: self.emojiAttributes )
        let layoutManager   = NSLayoutManager.init()
        let textContainer   = NSTextContainer.init( containerSize:
NSMakeSize( kSquareSize, kSquareSize ) )

        layoutManager.addTextContainer( textContainer )
        textStorage.addLayoutManager( layoutManager )

        let emoji               = textStorage
        let emojiLayout         = emoji.layoutManagers[0]
        let glyphRange          = NSMakeRange( 0,
emojiLayout.numberOfGlyphs )
        let emojiCoordinates    =
emojiLayout.lineFragmentUsedRectForGlyphAtIndex( 0,
effectiveRange: nil )
        let emojiLocation       = emojiLayout.locationForGlyphAtIndex( 0 )
        let emojiLocationFrame  = NSMakeRect( emojiLocation.x,
emojiLocation.y, emojiCoordinates.size.width,
emojiCoordinates.size.height )
        let emojiBoundingFrame  = emojiLayout.boundingRectForGlyphRange(
NSMakeRange( 0, emoji.length ), inTextContainer:
emojiLayout.textContainers[0] )
        let emojiUsedFrame      = emojiLayout.usedRectForTextContainer(
emojiLayout.textContainers[0] )

        NSColor.redColor().set()
        NSFrameRect( emojiCoordinates )

        NSColor.greenColor().set()
        NSFrameRect( emojiLocationFrame )

        NSColor.blueColor().set()
        NSFrameRect( emojiBoundingFrame )

        self.lightBlue.set()
        NSFrameRect( emojiUsedFrame )

        NSLog( "lineFragmentUsedRectForGlyphAtIndex %@", NSStringFromRect(
emojiCoordinates ) )
        NSLog( "locationForGlyphAtIndex             %@",
NSStringFromPoint( emojiLocation ) )
        NSLog( "boundingRectForGlyphRange           %@", NSStringFromRect(
emojiBoundingFrame ) )
        NSLog( "usedRectForTextContainer            %@", NSStringFromRect(
emojiUsedFrame ) )

        emojiLayout.drawGlyphsForGlyphRange( glyphRange, atPoint:
NSMakePoint( 0, 0 ) )
    }

The output from the logs is:

    lineFragmentUsedRectForGlyphAtIndex {{0, 0}, {32, 28}}
    locationForGlyphAtIndex             {5, 21}
    boundingRectForGlyphRange           {{5, 0}, {22, 28}}
    usedRectForTextContainer            {{0, 0}, {32, 28}}

The image is:

http://i.stack.imgur.com/F1eRA.png

I was expecting the emoji to be drawn in the lower left corner and do not
understand why is the character drawn so high. Why is the emoji drawn
where it is drawn?

I would like to understand how the text is being positioned so I can take
control over it and position the text where I need it to be positioned.

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to