Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How the "FBReader" do the pagination of html files in epub

I'm trying to make an epub reader

I want to do the pagination like fbreader does

Now I have source code of fbreader, but I don't know where it implement pagination

I have my implementation on other features

All I need from fbreader is the pagination

Is there anyone who have done the similar thing?

Thanks for your time to read this question.

ps: the pagination is to spit html file to pages, depending on the size of screen and size of font, and language is also in consideration, when changed the font size, the page number also changed. And epub file content is html format

like image 557
Qing Avatar asked May 17 '11 07:05

Qing


3 Answers

It is fascinating code. I would love to see a translation of the original student project (but I presume the original document is in Russian). As this is a port of a C++ project it has an interesting style of coding in places.

The app keeps track of where you are in the book by using paragraph cursors (ZLTextParagraphCursor). This situation is comparative with database cursors and record pagination. The class that is responsible for serving up the current page and calculating the number of pages is ZLTextView.

As epubs are reflowable documents and not page-oriented there isn't really a concrete definition of a page - it just depends on where in the document you happen to be looking (paragraph, word, character) and with what display settings.

like image 114
Mark McLaren Avatar answered Nov 18 '22 07:11

Mark McLaren


As McLaren says, FBReader doesn't implement pagination: It uses the ZLibrary, which is available from the same website as FBReader.

The original code uses this to calculate the current page number:

size_t ZLTextView::pageNumber() const {
    if (textArea().isEmpty()) {
        return 0;
    }
    std::vector<size_t>::const_iterator i = nextBreakIterator();
    const size_t startIndex = (i != myTextBreaks.begin()) ? *(i - 1) : 0;
    const size_t endIndex = (i != myTextBreaks.end()) ? *i : 
            textArea().model()->paragraphsNumber();
    return (myTextSize[endIndex] - myTextSize[startIndex]) / 2048 + 1;
}

The Java version uses this function to compute the page number:

private synchronized int computeTextPageNumber(int textSize) {
    if (myModel == null || myModel.getParagraphsNumber() == 0) {
        return 1;
    }

    final float factor = 1.0f / computeCharsPerPage();
    final float pages = textSize * factor;
    return Math.max((int)(pages + 1.0f - 0.5f * factor), 1);
}

This is located in org.geometerplus.zlibrary.text.view.TextView

It's so simplistic, though, that you might as well implement your own.

like image 32
jpaugh Avatar answered Nov 18 '22 07:11

jpaugh


How I understood it is that it uses 3 bitmaps previous current and next. What they have done is written a text which gets stored and read over this 3 bitmaps. Over as what you see on the top they calculate paragraphs data of how long it is for the scroll you see on the others example. You can start reverse engineering at android.view package class bitmapManager. This should explain everything about how they do their paging.

like image 2
wesdfgfgd Avatar answered Nov 18 '22 08:11

wesdfgfgd