Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There is any way to get current page and total pages? #286

Open
paulocoutinhox opened this issue May 13, 2017 · 9 comments
Open

There is any way to get current page and total pages? #286

paulocoutinhox opened this issue May 13, 2017 · 9 comments

Comments

@paulocoutinhox
Copy link

Hi,

There is any way to get current page and total pages?

Thanks.

@paulocoutinhox
Copy link
Author

I see example, and i get pages by chapter without problem. But i want get all pages like iBooks. There is a way? Thanks.

@danielweck
Copy link
Member

Related: readium/readium-js#16

@paulocoutinhox
Copy link
Author

paulocoutinhox commented May 22, 2017

My code to solve part of problems. It gets the page count by section/chapter. But i need get all pages count.

    func updateToolbar() {
        // total de página e página atual
        var pageDataText = ""
        
        if let currentPageOpenPagesArray = currentPageOpenPagesArray {
            if currentPageOpenPagesArray.count > 0 {
                var pageNumbers = [String]()
                
                for pageDict in currentPageOpenPagesArray {
                    let spineItemIndex: Int = pageDict["spineItemIndex"] as! Int
                    let spineItemPageIndex: Int = pageDict["spineItemPageIndex"] as! Int
                    let pageIndex = currentPageIsFixedLayout ? spineItemIndex : spineItemPageIndex
                    pageNumbers.append(String(pageIndex + 1))
                }
                
                let currentPages = pageNumbers.joined(separator: "-")
                var pageCount = 0
                
                if currentPageOpenPagesArray.count > 0 {
                    let firstOpenPageDict = currentPageOpenPagesArray[0]
                    let number: Int = firstOpenPageDict["spineItemPageCount"] as! Int
                    pageCount = currentPageIsFixedLayout ? currentPageSpineItemCount : number
                }
                
                // isto pode ser necessário lá na frente 
                //let pageType = currentPageIsFixedLayout ? "FXL" : "reflow"
                
                pageDataText = String(format: "Página: %@ de %@", currentPages, String(pageCount))
            }
        }
        
        readerBottomOptions?.lbPage.text = pageDataText
    }

@danielweck
Copy link
Member

Yes, there is a similar implementation in Readium SDK Launcher-iOS:
https://github.com/readium/SDKLauncher-iOS/blob/master/Classes/EPubViewController.m#L640-L670

	if (m_currentPageOpenPagesArray == nil || [m_currentPageOpenPagesArray count] <= 0) {
		label.text = @"";
	}
	else {

        NSMutableArray *pageNumbers = [NSMutableArray array];

        for (NSDictionary *pageDict in m_currentPageOpenPagesArray) {

            NSNumber *spineItemIndex = [pageDict valueForKey:@"spineItemIndex"];
            NSNumber *spineItemPageIndex = [pageDict valueForKey:@"spineItemPageIndex"];

            int pageIndex = m_currentPageIsFixedLayout ? spineItemIndex.intValue : spineItemPageIndex.intValue;

            [pageNumbers addObject: [NSNumber numberWithInt:pageIndex + 1]];
        }

        NSString* currentPages = [NSString stringWithFormat:@"%@", [pageNumbers componentsJoinedByString:@"-"]];

        int pageCount = 0;
        if ([m_currentPageOpenPagesArray count] > 0)
        {
            NSDictionary *firstOpenPageDict = [m_currentPageOpenPagesArray objectAtIndex:0];
            NSNumber *number = [firstOpenPageDict valueForKey:@"spineItemPageCount"];

            pageCount = m_currentPageIsFixedLayout ? m_currentPageSpineItemCount: number.intValue;
        }
        NSString* totalPages = [NSString stringWithFormat:@"%d", pageCount];

        label.text = LocStr(@"PAGE_X_OF_Y", [currentPages UTF8String], [totalPages UTF8String], m_currentPageIsFixedLayout?[@"FXL" UTF8String]:[@"reflow" UTF8String]);
	}

@paulocoutinhox
Copy link
Author

paulocoutinhox commented May 29, 2017

Hi, i already do it im my project. But it get the current and total pages for the current "chapter".

func updateToolbar() {
        // total de páginas e página atual
        pageDataText = ""
        
        if let currentPageOpenPagesArray = currentPageOpenPagesArray {
            if currentPageOpenPagesArray.count > 0 {
                var pageNumbers = [String]()
                
                for pageDict in currentPageOpenPagesArray {
                    let spineItemIndex: Int = pageDict["spineItemIndex"] as! Int
                    let spineItemPageIndex: Int = pageDict["spineItemPageIndex"] as! Int
                    let pageIndex = currentPageIsFixedLayout ? spineItemIndex : spineItemPageIndex
                    pageNumbers.append(String(pageIndex + 1))
                }
                
                let currentPages = pageNumbers.joined(separator: "-")
                var pageCount = 0
                
                if currentPageOpenPagesArray.count > 0 {
                    let firstOpenPageDict = currentPageOpenPagesArray[0]
                    let number: Int = firstOpenPageDict["spineItemPageCount"] as! Int
                    pageCount = currentPageIsFixedLayout ? currentPageSpineItemCount : number
                }
                
                // isto pode ser necessário lá na frente
                //let pageType = currentPageIsFixedLayout ? "FXL" : "reflow"
                
                pageDataText = String(format: "Página: %@ de %@", currentPages, String(pageCount))
            }
        }
        
        readerBottomOptions?.lbPage.text = pageDataText
}

But i want get the total pages of all chapters/spines.

@cuneyttyler
Copy link

Hi @paulocoutinhox, did you manage to get current page no and total page count?

@guidomagaldi
Copy link

Hello @cuneyttyler , did you manage to do it?

@cuneyttyler
Copy link

@guidomagaldi Yes, I calculated the current page by considering the sizes of each chapter files and looking at the percentage of scroll in the current chapter. I assumed the size of one page is 7 kb. You can use the code below:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class PageCalculator {
    private Map<String, Long> sizeMap = new LinkedHashMap<>();
    private long totalSize;
    private int bytesPerPage = 7000;

    public PageCalculator(String filePath) throws IOException {
        calcTotalSize(filePath);
    }

    private void calcTotalSize(String filePath) throws IOException {
        ZipFile zip = new ZipFile(filePath);

        String content = null;
        for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            if (!entry.isDirectory() && entry.getName().contains("content.opf")) {
                content = getTxtFiles(zip.getInputStream(entry));
            }
        }

        Document doc = Jsoup.parse(content);
        Elements spines = doc.getElementsByTag("package").first().getElementsByTag("spine").first().getElementsByTag("itemref");
        List<String> chapterFileNames = new ArrayList<>();
        for (Element el : spines) {
            String id = el.attr("idref");
            if(el.attr("linear") == null || !el.attr("linear").equals("no")) {
                String chapter = doc.getElementsByTag("package").first().getElementById(id).attr("href");
                chapterFileNames.add(chapter);
            }
        }

        for(String chapter: chapterFileNames) {
            for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) e.nextElement();
                if (!entry.isDirectory() && entry.getName().contains(chapter)) {
                    sizeMap.put(entry.getName(), entry.getSize());
                }
            }
        }

        totalSize = sizeMap.values().stream().reduce(0l,Long::sum);
    }

    public int getTotalPages() {
        return (int)(totalSize / bytesPerPage);
    }

    public int getCurrentPage(int percent, int chapterIndex) {
        long prevSize = 0;
        int i = 0;
        for(String chapter: sizeMap.keySet()) {
            if(chapterIndex == i) {
                break;
            }
            i++;
            prevSize += sizeMap.get(chapter);
        }

        Long currentChapterSize = (Long) sizeMap.values().toArray()[chapterIndex];
        double currentChapterSizePerc = currentChapterSize.doubleValue() * ((double)percent/100);

        return (int)((prevSize + currentChapterSizePerc ) / bytesPerPage );
    }

    public class ProgressResponse {
        public int chapterIndex;
        public double viewScrollMarginPerc;

        public ProgressResponse(int chapterIndex, double viewScrollMarginPerc) {
            this.chapterIndex = chapterIndex;
            this.viewScrollMarginPerc = viewScrollMarginPerc;
        }
    }

    public ProgressResponse getPageFromProgressPercentage(double percent) {
        double percSize = (percent * totalSize);

        int tempSize = 0;
        int progressChapterIndex = 0;
        long progressChapterSize = 0;
        for(int i = 0; i < sizeMap.size(); i++) {
            String chapter = (String) sizeMap.keySet().toArray()[i];
            long size = sizeMap.get(chapter);

            tempSize += size;
            if(tempSize > percSize) {
                progressChapterIndex = i;
                progressChapterSize = size;
                break;
            }
        }

        int prevSize = 0;
        for(int i = 0; i < progressChapterIndex; i++) {
            String chapter = (String) sizeMap.keySet().toArray()[i];
            long size = sizeMap.get(chapter);
            prevSize += size;
        }

        double viewScrollMarginPerc = (percSize - prevSize) / progressChapterSize;

        return new ProgressResponse(progressChapterIndex,viewScrollMarginPerc - 0.02);
    }

    private static String getTxtFiles(InputStream in) {
        StringBuilder out = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                out.append(line);
            }
        } catch (IOException e) {
            // do something, probably not a text file
            e.printStackTrace();
        }
        return out.toString();
    }
}

@guidomagaldi
Copy link

@cuneyttyler I will try this, thank you for your time! I really appreciate it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants