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