mozilla/pdf.js — pull request #1205 by arturadib (2012-02-13 21:26:32+00:00)
Title: Prototype: Canvas-based text selection backend

This prototype was implemented during our workweek, inspired by conversations with @ironymark. I wanted to get more feedback about the overall direction I'm heading before spending more time on it.

Our current text selection algorithm (based on textual divs) suffers from the following problems:

+ **What-You-Select-Is-Not-What-You-Get (WYSINWYG)**: This is an issue particularly for international documents (e.g. Chinese, Arabic, etc). Because the algo lumps characters into a single div, we can't reproduce the subtle character spacings that come with the `showSpacedText()` command. Consequently the selected characters do not necessarily match the ones we see in the underlying canvas.
+ **Impractical for "letter-by-letter" docs** (i.e. docs that use one `showText()` command per character): The algorithm was designed assuming that all documents use one `showSpacedText()` per line, and makes some expensive calculations/adjustments after each div. Some generators do not obey this rule (e.g. https://github.com/mozilla/pdf.js/issues/1045), and hence lead to impractically large CPU usage.
+ **Selection jerkiness**: Because the divs have to be absolutely positioned, the layout engine resets the selection region every time the mouse falls outside the immediate vicinity of text. So the user needs to be precise in where they place the mouse, which is unusual.

Because of the above, I've started prototyping a new selection backend using pure Canvas -- there is no text in the DOM. This gives us much more flexibility in terms of how the selection should behave, leads to a much faster overhead, and lets us select exactly the text one sees in the canvas.

However, there are challenges:

+ **LTR, RTL**: We'll still need to think about how to support both LTR and RTL, perhaps reuse some of @ironymark's #1202.
+ **Scrolling**: When the user tries to select text beyond the allowed region (e.g. beyond the bottom) the browser does _not_ scroll automatically. I've prototyped the desired behavior somewhat in the current algorithm. (Should this be a platform feature?)
+ **Accessibility**. This is actually a challenge for both implementations, as it isn't working in our current implementation. I understand the HTML5 spec for canvas allows the use of a "caret" to help with keyboard navigation and text selection (http://www.w3.org/TR/2dcontext/#caret-selection). I'm not saying this is the best solution; we'd have to research what our options are.
+ **Won't work with docs that don't have letter ordering**: This is also a problem with the current algorithm. In the new one, I too make the assumption that the letters have a specific ordering associated with them (whether it's LTR or RTL). Without this we'd have to either perform a layout analysis, or fallback to simple rectangular selection.