Since attachments consist of a single (non visible) glyph (0xFFFC) you can use the glyph messages to get the bounding box. Here's code I use to highlight an attachment in an NSTextView based on the mouse position (which requires to get attachment bounds):
/**
* Determines the index under the mouse. For highlighting we use the index only if the mouse is actually
* within the tag bounds. For selection purposes we return the index as it was found even if the mouse pointer
* is outside the tag bounds.
*/
- (NSUInteger)updateTargetDropIndexAtPoint: (NSPoint)point
{
CGFloat fraction;
NSUInteger index = [self.layoutManager glyphIndexForPoint: point
inTextContainer: self.textContainer
fractionOfDistanceThroughGlyph: &fraction];
NSUInteger caretIndex = index;
if (fraction > 0.5) {
caretIndex++;
}
// For highlighting a tag we need check if the mouse is actually within the tag.
NSRect bounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(index, 1)
inTextContainer: self.textContainer];
NSUInteger newIndex;
if (NSPointInRect(point, bounds)) {
newIndex = index;
} else {
newIndex = NSNotFound;
}
if (hotTagIndex != newIndex) {
NSRect oldBounds = [self.layoutManager boundingRectForGlyphRange: NSMakeRange(hotTagIndex, 1)
inTextContainer: self.textContainer];
[self setNeedsDisplayInRect: oldBounds];
hotTagIndex = newIndex;
[self setNeedsDisplayInRect: bounds];
}
return caretIndex;
}
This code is used in an NSTextView descendant, hence the self.layoutManager access.