|
Produce two arrays of line start (offset of character from start of string) and line length (pixels).
Each line is terminated at an embedded CR or LF (CRLF counts as one break) or wraps at the nearest word boundary. Word gaps detected as spaces and tabs.
Line separator characters (CR etc) are skipped by adjustment of the line start positions. An empty line will create an entry with a length of 0 and a line start of the terminator.
Calling StoreLineStart will expand both arrays as suited, it must therefore be called first. This updates the mNumRows member which is used (via GetNumRows()) by all clients.
Note that each time we start a line we must re-measure it as proportional fonts will vary width depending on context. We avoid remeasuring to the end of a very large block by making an assumption that a line will exceed a threshold of 500 characters in a single line. (kMaxCharsInSingleLine defined below)
We also pre-scan for terminators as it is more likely that typical text will have lines much shorter than kMaxCharsInSingleLine.
- Todo:
- Could make it smarter when we have to wrap inside a terminator by looping up until that terminator rather than going to the top of the main loop again.
MAIN ALGORITHM Repeat if starts with terminator skip terminator make entry for blank line else pre-scan forward for line terminators, up to kMaxCharsInSingleLine if no terminators in this limit, measure up to kMaxCharsInSingleLine else measure up to terminator scan array of sizes to see if fits in fixed line length (pixels, not number of chars) if line too long scan backwards from stopping point to first word break finish line entry |