13

I'm building an e-Book reader for android. The content of an ebook is often divided into html files (epub) with one or may chapters in them.

I'm planning to build an e-book reader who divides the content of those files into different "pages". The problem is to know how many much text "fits" on one page and to calculate the correct amount of pages since that depends on a number of different factors, such as: font-size, word size, paragraphs, images, page-breaks, headlines etc.

Idealy i would have my text justified and selectable, and since that's not possible with normal TextView or EditText i must use a non-scrollable WebView.

So to sum it up, how can i "measure" how much text that fits on one "page" on my WebView? Or is there a different better approach to solve this? I saw that the Paint class as support for measure text and breakText.

Thanks!

Richard
  • 14,427
  • 9
  • 57
  • 85
  • I would seriously rethink the idea of setting your text justified as it is known to be less readable: http://www.newsletterfillers.com/archives/design/justified_ragged.htm – Joeri Minnekeer Mar 07 '12 at 08:24

3 Answers3

7

Note : This answer does not use the webview as your display surface.

You can use the Canvas to draw each page. The canvas gives you it's height & width using which you can draw each line on the canvas using drawText based on the width & height available.

Basically you can calculate how many letters can fit in a line , take that many words , taking care you don't split any words and keep drawing the text.

If you break up the tasks to use different workers for each paragraph you can also probably make it fast.

Ravi Vyas
  • 12,212
  • 6
  • 31
  • 47
  • using canvas prevents me from being able to select text and have justification to it :/ – Richard Mar 07 '12 at 09:09
  • 2
    You can solve that too. If you can keep a map of which char is where on the the screen.. you can follow the uers's selection dialog [ which now can be a rectangle too] and flip the text colors between those coordinates to show they are selected. Its more of a work around but it should work :) . – Ravi Vyas Mar 07 '12 at 11:04
3

Maybe you can do it like this

  • Text is being added and rendered inside WebView

  • In WebView, you can use Javascript to inspect the current state of DOM tree and extract measurements like width and height of individual elements

  • Javascript communicates back the size of the page back to WebView creator thru some callback

  • When Javascript detects that the page size threshold is exceeded it sends a signal for a page break needed

Android HTML5 Kindle does page breaking with Javascript so it is definitely possible.

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
  • Tried filling up a div inside my webview html untill it got overflown using this function but its dead slow :/ http://stackoverflow.com/questions/143815/how-to-determine-using-javascript-if-html-element-has-overflowing-content – Richard Feb 06 '12 at 22:03
  • That particular answer is not very smart. There is tons of ways to optimize it and Kindle can do the whole book paging in JS. – Mikko Ohtamaa Feb 07 '12 at 10:49
  • For example, operate on paragraphs or sentences instead of individual chars or words. – Mikko Ohtamaa Feb 07 '12 at 10:52
  • Well i was working on sentences and it's not fast at all. Java execution from android runs in a separate thread and communication back to android from javascript using javascript interface is dead slow so not an option im afraid :/ – Richard Feb 29 '12 at 13:38
  • Ah. That's bottleneck on Android - didn't think about that :( Can you reduce the amount of communication to whole pages? – Mikko Ohtamaa Feb 29 '12 at 19:33
2

Take a look at the source of FitText or perhaps here. Both figure how much text can fit in a given space. You may be able to borrow ideas from them and adapt for your purposes.

NuSkooler
  • 5,391
  • 1
  • 34
  • 58