Calculating Region, Bounding Rectangle, and Inset

An NSTextContainer object’s region is defined by a bounding rectangle whose coordinate system starts at (0,0) in the top-left corner. The size of this rectangle is returned by the containerSize method and set using setContainerSize:. You can define a container’s region so that it’s always the same shape, such as a circle whose diameter is the narrower of the bounding rectangle’s dimensions, or you can define the region relative to the bounding rectangle, such as an oval region that fits inside the bounding rectangle (and that’s a circle when the bounding rectangle is square). Regardless of a text container’s shape, its NSTextView always clips drawing to its bounding rectangle. Figure 1 illustrates these aspects of a text container.

Figure 1  Text container region, bounding rectangle, and inset
Text container region, bounding rectangle, and inset

A subclass of NSTextContainer defines its region by overriding three methods. The first, isSimpleRectangularTextContainer, indicates whether the region is currently a non-rotated rectangle, thus allowing the NSLayoutManager to optimize layout of text (since custom text containers typically define more complex regions, your implementation of this method will probably return NO). The second method, containsPoint:, is used for testing mouse events and determines whether or not a given point lies in the region. The third method, lineFragmentRectForProposedRect:sweepDirection:movementDirection:remainingRect:, is used for the actual layout of text, defining the region in terms of rectangles available to lay text in. This process is described in Line Fragment Generation

A text container usually covers its text view exactly, but it can be inset within the view frame with the setTextContainerInset: method. The text container’s bounding rectangle from the inset position then establishes the limits of the text container’s region. The inset also helps determine the size of the bounding rectangle when the text container tracks the height or width of its text view, as described in Tracking the Size of a Text View.

Note that the text container inset does not fully determine the position of the container in the text view. The text view calculates the position of the text container within it, and it tries to maintain the amount of space given by the text container inset, but depending on the relative sizes of the text view and text container, that may not be possible. It’s also possible that there’s more space to be distributed than that specified by the text container inset. If you want to determine the true location of the text container—for example, to convert between container and view coordinates—you should use the textContainerOrigin method, which is the actual value calculated by the text view.