阅读器的进度显示与估计


对电子书阅读器来说,提示当前阅读进度是一项很自然的功能,习惯用电脑的人都常看到进度条 (progress bar) 和滚动条 (scroll bar),如右图是 [Textus](http://www.jjgod.org/projects/textus) 中使用的右侧滚动条。

然而在实际实现中,进度计算是一件伤脑筋的事情,比如 Textus 的实现其实很简单:在打开文件时读入整个文件,然后整个交给 [Core Text](http://en.wikipedia.org/wiki/Core_Text) 去排版,将排版后的结果分解为行 (`CTLineRef`) 记录下来,并将所有行总的高度设置为整个文本视图的高度,这样,每当滚动视图 (`NSScrollView`) 移动到某个位置时,重绘函数 (`-drawRect:`) 被调用到,我们根据该位置来判断应该绘制从第几行到第几行的内容,再调用 Core Text 把这些行画出来。

这么做看似很简单直接,结果也很容易保证正确,带来的问题是,每次用户修改设置 (比如调整字体大小、窗口尺寸) 时,就得把整个文件重新排版一遍,即使此时我们只需要看到**当前一页**的内容。为什么这种方法这么低效,我还一直使用它呢?因为这个实现严格依赖滚动视图给出的位置来判断当前阅读进度,所以总的高度估计必须非常精确,不然随便滚动一下就可能出现错位,而一次算给出整个高度的方法最准确,不容易出错。

Continue reading “阅读器的进度显示与估计”

A closer look at Classics.app

A Screenshot of Classics

“[Classics](http://www.classicsapp.com/)” is a great product, it shows us iPhone developers what an *elegant* ebook reader can be, so I bought it almost instantly after it’s released. I’ve been chatting with my friends about this app for a while, now I’d like to give a more closer examination to it from the perspective of a typographer and a programmer. Especially its weaknesses.

Illustrated by my favorite graphic designer, [David Lanham](http://dlanham.com), Classics tries its best to provide a traditional book reading experience (that’s why it’s called “Classics”). It contains the following books, even I’ve read most of them in Chinese long time ago, thanks to Classics, it’s still a fascinating experience to read them again in English:

* *[20,000 Leagues Under the Sea](http://en.wikipedia.org/wiki/Twenty_Thousand_Leagues_Under_the_Sea)* by [Jules Verne](http://en.wikipedia.org/wiki/Jules_Verne)
* *[A Christmas Carol](http://en.wikipedia.org/wiki/A_Christmas_Carol)* by [Charles Dickens](http://en.wikipedia.org/wiki/Charles_Dickens) [Added in version 1.1]
* *[Alice in Wonderland](http://en.wikipedia.org/wiki/Alice_in_Wonderland)* by [Lewis Carroll](http://en.wikipedia.org/wiki/Lewis_Carroll)
* *[Flatland](http://en.wikipedia.org/wiki/Flatland)* by [Edwin Abbott Abbott](http://en.wikipedia.org/wiki/Edwin_Abbott_Abbott)
* *[Gulliver’s Travels](http://en.wikipedia.org/wiki/Gulliver%27s_Travels)* by [Jonathan Swift](http://en.wikipedia.org/wiki/Jonathan_Swift)
* *[The Hound of the Baskervilles](http://en.wikipedia.org/wiki/Hound_of_the_Baskervilles)* by Sir [Arthur Conan Doyle](http://en.wikipedia.org/wiki/Arthur_Conan_Doyle)
* *[Adventures of Huckleberry Finn](http://en.wikipedia.org/wiki/Adventures_of_Huckleberry_Finn)* by [Mark Twain](http://en.wikipedia.org/wiki/Mark_Twain)
* *[Paradise Lost](http://en.wikipedia.org/wiki/Paradise_Lost)* by [John Milton](http://en.wikipedia.org/wiki/John_Milton)
* *[Robinson Crusoe](http://en.wikipedia.org/wiki/Robinson_Crusoe)* by [Daniel Defoe](http://en.wikipedia.org/wiki/Daniel_Defoe)
* *[The Call of the Wild](http://en.wikipedia.org/wiki/The_Call_Of_The_Wild)* by [Jack London](http://en.wikipedia.org/wiki/Jack_London)
* *[The Jungle Book](http://en.wikipedia.org/wiki/The_Jungle_Book)* by [Rudyard Kipling](http://en.wikipedia.org/wiki/Rudyard_Kipling)
* *[The Metamorphosis](http://en.wikipedia.org/wiki/The_Metamorphosis)* by [Franz Kafka](http://en.wikipedia.org/wiki/Franz_Kafka)
* *[The Time Machine](http://en.wikipedia.org/wiki/The_Time_Machine)* by [H. G. Wells](http://en.wikipedia.org/wiki/H._G._Wells)

However, there are still some details to be improved.
Continue reading “A closer look at Classics.app”