Implement line breaking in native code

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
2 files changed