Question

I need to perform efficient hit testing against a (potentially huge) number of components so I've represented all my primitives as NSBezierPath instances. All working great so far.

Now I'm having trouble converting NSString objects, in particular reflecting their position in the view: I'm using the NSString (BezierConversions) category from Apple's SpeedometerView example to convert strings into bezier paths.

The bezier path created for strings looks great but positioning it to match the position of the NSString instances location in the view doesn't quite work so I suppose this question is really about

  • NSBezierPath and transformUsingAffineTransform: vs.
  • a combination of NSAffineTransform applied to a view and NSString drawAtPoint:

In my test project even the trivial case fails:

Purple = NSString drawAtPoint, Grey = NSBezierPath fill

Grey bezier representation of string drawn using:

NSAffineTransform *moveFinal = [NSAffineTransform transform];
[moveFinal translateXBy:x yBy:y];
[textBezier transformUsingAffineTransform:moveFinal];

and the purple string via

[testString drawAtPoint:NSMakePoint(x, y)
        withAttributes:attributes];

Same attributes, same input positions, different location in view.
And it just gets worse with rotated text.


UPDATE #1

Looks like it's boiling down to different bounding boxes returned by

  • NSString sizeWithAttributes:
  • NSBezierPath bounds

Now experimenting with NSString boundingRectWithSize

Était-ce utile?

La solution

FWIW - Working now.

Using boundingRectWithSize:options:attributes: with the NSStringDrawingUsesDeviceMetrics option gives some good text dimensions to work with, including the actual bounding box occupied by the string when drawn and the offset of the first glyph.

Offset the NSBezierPath returned from bezierWithFont: by that amount and you're good to go..

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top