Calculating Lines of Text

  • How can I get at the bounding rects for wrapped text in each cell of
    an NSTableColumn? The following explains why I want to know, and what
    I've tried so far.

    I have an NSTable view for which I'm calculating -
    tableView:heightOfRow:. I'm causing this calculation to take place
    whenever -controlTextDidChange is called (by calling -reloadData:),
    so that I get live resizing of rows as text is typed into them. (Live
    resizing is a preference that can be turned off by the user, with
    resizing triggered by a hot key.) And, of course, the calculation is
    also carried out whenever -reloadData: is called for other reasons.

    There is only one column involved in the calculation, and I know the
    cell content for each row and the height requirement for a single
    line of text, based on the font. (It's monostyled text only.)

    What I need to calculate for each cell is either (1) how many lines
    of text will appear or (2) the height of the rect required to display
    the wrapped text (the width of the frame being the -width: of the
    column).

    I first tried (1), using NSFont's (now deprecated) -widthOfString:,
    dividing it by the column width to get a line count. This doesn't
    produce an accurate line count, because some lines end up longer than
    expected, due to the way wrapping works--some extra blank space can
    occur at the end of lines when a word gets bumped down to the next
    line. The result is that I can end up with a row that's one line too
    short (vertically).

    Next I tried (2). Not knowing how to get the frame that is actually
    used by the cells themselves for drawing text, I've experimented with
    shoving the text into an NSTextView with the appropriate font set,
    and with a width that matches the column width, and then using
    NSLayoutManager's -boundingRectForGlyphRange:inTextContainer: to get
    a bounding rect. The first result is a rect with a height that, for
    some reason, is not an even multiple of the text line height as drawn
    in the table cell. I've tried regularizing that on the basis of the
    number of lines calculated in method (1), but sometimes end up with
    an extra empty line. That may just be the result of programming too
    late without coffee, and I'm sure I can figure out where I've gone
    wrong.

    However, the big problem with using a separate text view for these
    calculations is that it slows down typing by quite a bit--especially
    on non-Intel machines. If I could just look at each cell of the
    column, that should be much faster, but I haven't found how that can
    be done. I've optimized method (2) by keeping NSTextView and NSFont
    variables on hand, but the process is still complex and extremely
    slow. Even resizing the window or the enclosing view can get very
    jerky--regardless of whether live resizing is turned on or not.

    Any suggestions? As I said at the beginning, what I would really like
    is some way to get at the actual text bounding rects for all the
    cells in the column, but if that's not possible, something more
    efficient than my method (2) would be nice. I can provide some code
    to critique if it comes to that.

    Thanks,
    Mike Wright
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today