The main purpose for this change is to prepare for adding support for
alternative line breaking algorithms (such as optimal line breaking).
The existing implementation of line breaking was intertwined with
measurement, so it wasn't structured in a way such that other line
breaking algorithms could be easily added. In addition to this,
algorithms (such as optimal line breaking) are usually fairly complex
and computation-intensive, so it is advantageous to implement them in
native code.
This has several other advantages:
* Unlike the Java code in the previous version of generate(), this
implementation separates line breaking from measurement. This
makes it easier to understand and modify the line breaking process
without affecting measurement (and vice versa).
* This native implementation of greedy line breaking is identical to
the Java version in terms of functionality, and it is similar in
terms of performance, depending on the use case. The performance
gains from this change are not significant due to increased JNI
overhead. However, this change is a step in the right direction in
terms of increasing performance. Once more code moves to C++,
there will be fewer JNI crossings per layout call and less data
will be passed from Java to C++, resulting in better performance.
This change moves line breaking from Java to native C++ code. Inspired
by the "Breaking Paragraphs into Lines" paper by Knuth and Plass (1981),
we express the line breaking problem in terms of 'box', 'glue', and
'penalty' primitives, along with a few others. Our implementation
differs in a couple ways:
* We do not want to clip text when words are wider than the view, so
we add a new primitive type to represent break opportunities
between letters. These breaks are avoided whenever possible, but
when single words do not fit on lines by themselves, they can be
broken so the entire word is visible.
* We have to support tab characters, along with user*specified tab
stops, so we add a new primitive type for that purpose.
* We are left*aligning text, and so we are not using shrinking /
stretching glue.
* We do not support hypenation, so we do not use penalties that have
widths.
Change-Id: Ia22d1d1275ef26ff3d7b41ee2658e4db525a0305