Apple的Doc對這個類的描述是這樣的:
The NSTextContainer class defines a region where text is laid out. An NSLayoutManager uses NSTextContainer to determine where to break lines, lay out portions of text, and so on. NSTextContainer defines rectangular regions, but you can create subclasses that define regions of other shapes, such as circular regions, regions with holes in them, or regions that flow alongside graphics.
NSTextContainer定義了一個擺放text的區域。NSLayoutManager就是使用這個區域來決定何時break line,排放部分text或者其他行為。NSTextContainer定義了矩形區域,但可以繼承這個類並定義任意形狀的區域。
TextLayoutDemo定義了一個圓形區域,以此為例,學習一下。
- (NSRect)lineFragmentRectForProposedRect:(NSRect)proposedRect sweepDirection:(NSLineSweepDirection)sweepDirection movementDirection:(NSLineMovementDirection)movementDirection remainingRect:(NSRectPointer)remainingRect
這個方法是這個類的核心方法。proposedRect是一個提議的矩形區域,但這個區域的寬度、位置可能很不靠譜,比如width可能非常大,遠超過bounding rectangle。
The receiver should examine proposedRect to see that it intersects its bounding rectangle and should return a modified rectangle based on sweepDirection and movementDirection, whose possible values are listed in the class description. If sweepDirection is NSLineSweepRight, for example, the receiver uses this information to trim the right end of proposedRect as needed rather than the left end.
If proposedRect doesn’t completely overlap the region along the axis of movementDirection and movementDirection isn’t NSLineDoesntMove, this method can either shift the rectangle in that direction as much as needed so that it does completely overlap, or return NSZeroRect to indicate that the proposed rectangle simply doesn’t fit.
這里提到了sweepDirection,這個參數的可選值有:NSLineSweepLeft , NSLineSweepRight ,NSLineSweepDown , NSLineSweepUp 。這個參數(line sweep) 描述行內text的方向,大部分text都是從左向右書寫的,但是繁體中文的書有不少都是從上往下書寫的,而阿拉伯文是從右往左書寫的。我們計算可用空間與proposedRect的intersect時,需要考慮文字的書寫方向。
另外一個參數是movementDirection,這個參數的可選值有: NSLineDoesntMove , NSLineMovesLeft , NSLineMovesRight,NSLineMovesDown , NSLineMovesUp。也就是寫完一行后,下一行往哪里寫?上下左右都可以,還有就是不動DontMove。
When the typesetter generates line fragments, the text container is particularly concerned with the direction in which text layout proceeds. There are two aspects to layout direction: line sweep and line movement. Line sweep is the direction in which the system lays out glyphs within lines. Line movement is the direction in which the system lays out lines upon the page. The typesetter object determines these parameters and passes them as constant values to the text container. Both line sweep and line movement can proceed from left to right, right to left, top to bottom, and bottom to top. In addition, the typesetter can specify no line movement.
Note: The built-in typesetters currently support only top-to-bottom line movement and left-to-right sweep. These typesetters do handle bidirectional text (Hebrew and Arabic) by laying it out in the proper display order within the line fragments, but they do not use the line sweep mechanism.
Apple這是夠扯淡,本來sweep就是用來支持Arabic的一種技術,可是偏到這個時候又不管用了,用什么別的技術實現,這是說明API設計的不夠好嗎?
Reference
1. https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/TextStorageLayer/Concepts/LayoutGeometry.html#//apple_ref/doc/uid/20001803-CJBJHGAG
2. https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSTextContainer_Class/Reference/Reference.html#//apple_ref/doc/uid/20000368-1951