readium-sdk icon indicating copy to clipboard operation
readium-sdk copied to clipboard

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

Open paulocoutinhox opened this issue 7 years ago • 9 comments

Hi,

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

Thanks.

paulocoutinhox avatar May 13 '17 02:05 paulocoutinhox

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

paulocoutinhox avatar May 13 '17 08:05 paulocoutinhox

Related: https://github.com/readium/readium-js/issues/16

danielweck avatar May 21 '17 08:05 danielweck

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
    }

paulocoutinhox avatar May 22 '17 18:05 paulocoutinhox

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]);
	}

danielweck avatar May 27 '17 21:05 danielweck

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.

paulocoutinhox avatar May 29 '17 16:05 paulocoutinhox

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

cuneyttyler avatar Dec 21 '22 08:12 cuneyttyler

Hello @cuneyttyler , did you manage to do it?

guidomagaldi avatar Jan 10 '23 11:01 guidomagaldi

@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();
    }
}

cuneyttyler avatar Jan 10 '23 12:01 cuneyttyler

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

guidomagaldi avatar Jan 10 '23 12:01 guidomagaldi