All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.display.MultiPageDecoder Maven / Gradle / Ivy

There is a newer version: 20151002
Show newest version
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2015 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * MultiPageDecoder.java
 * ---------------
 */

package org.jpedal.display;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.Semaphore;
import org.jpedal.FileAccess;
import org.jpedal.PdfDecoderInt;
import org.jpedal.constants.SpecialOptions;
import static org.jpedal.display.Display.CONTINUOUS;
import static org.jpedal.display.Display.CONTINUOUS_FACING;
import static org.jpedal.display.Display.FACING;
import static org.jpedal.display.Display.SINGLE_PAGE;
import static org.jpedal.display.Display.debugLayout;
import org.jpedal.external.Options;
import org.jpedal.external.RenderChangeListener;
import org.jpedal.gui.GUIFactory;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.AcroRenderer;
import org.jpedal.objects.raw.PageObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.parser.*;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.text.TextLines;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.repositories.Vector_Int;
import org.jpedal.utils.repositories.generic.Vector_Rectangle_Int;

/**
 *
 * @author markee
 */
public abstract class MultiPageDecoder {

    private final Semaphore semaphore=new Semaphore(1);

    final GUIFactory gui;
    
    //used to redraw multiple pages
    private Thread worker;
     
    public final Map currentPageViews=new HashMap();
    
    private final FileAccess fileAccess;

    private final PdfObjectReader currentPdfFile;
    
    private final AcroRenderer formRenderer;

    private int displayView;
    
    private Map cachedPageViews=new WeakHashMap();

    private final MultiPagesDisplay display;
    
    private RenderChangeListener customRenderChangeListener;
    
    //facing mode drag pages
    private final BufferedImage[] facingDragCachedImages = new BufferedImage[4];
    private BufferedImage facingDragTempLeftImg, facingDragTempRightImg;
    private int facingDragTempLeftNo, facingDragTempRightNo;

    private final MultiDisplayOptions multiDisplayOptions;
   
    public final PdfDecoderInt pdf;
    
    private final PdfPageData pageData;
    
    final DecoderOptions options;
    
    final DisplayOffsets offsets;
    
    public MultiPageDecoder(final GUIFactory gui,final PdfDecoderInt pdf,final PdfPageData pageData,final MultiPagesDisplay display, final MultiDisplayOptions multiDisplayOptions, 
            final DynamicVectorRenderer currentDisplay, final int pageNumber,final FileAccess fileAccess, 
            final PdfObjectReader io, final AcroRenderer formRenderer,final DecoderOptions options) {
       
        this.gui=gui;
        this.pdf=pdf;
        this.pageData=pageData;
       
        this.display=display;
        this.multiDisplayOptions=multiDisplayOptions;
        this.fileAccess=fileAccess;
        this.currentPdfFile=io;
        this.formRenderer=formRenderer;
        this.options=options;
        
        offsets=(DisplayOffsets) pdf.getExternalHandler(Options.DisplayOffsets);
        
        /**cache current page*/
        if(currentDisplay!=null) {
            currentPageViews.put(pageNumber, currentDisplay);
        }
    }
    
    /**used to decode multiple pages on views*/
    public void decodeOtherPages(int pageNumber, final int pageCount,int displayView, PdfDecoderInt pdf) {
        
        try {
            semaphore.acquire();
        } catch (InterruptedException ex) {
            LogWriter.writeLog("Exception: " + ex.getMessage());
        }
        
        this.displayView=displayView;
        
        if(debugLayout) {
            System.out.println("start decodeOtherPages " + pageNumber + ' ' + pageCount);
        }

        //Ensure page range does not drop below one
        if(pageNumber<1) {
            pageNumber = 1;
        }

        final int oldPN = multiDisplayOptions.getPageNumber();
        multiDisplayOptions.setPageNumber(pageNumber);

        //Store the image to be used instead of filling the borders with white
        if (displayView==FACING && multiDisplayOptions.isTurnoverOn()) {
             final int lp;
            if (multiDisplayOptions.isSeparateCover()) {
                lp = (oldPN / 2) * 2;
            } else {
                lp = oldPN - (1 - (oldPN & 1));
            }
            if (offsets.getDragLeft()) {
                facingDragTempLeftImg = facingDragCachedImages[0];
                facingDragTempLeftNo = lp-2;
                facingDragTempRightImg = facingDragCachedImages[1];
                facingDragTempRightNo = lp-1;
            } else {
                facingDragTempLeftImg = facingDragCachedImages[2];
                facingDragTempLeftNo = lp+2;
                facingDragTempRightImg = facingDragCachedImages[3];
                facingDragTempRightNo = lp+3;
            }
        }

        facingDragCachedImages[0]=null;
        facingDragCachedImages[1]=null;
        facingDragCachedImages[2]=null;
        facingDragCachedImages[3]=null;

        calcDisplayedRange();

        while(multiDisplayOptions.isRunning()){
            try {
                Thread.sleep(100);
            } catch (final InterruptedException e) {
                LogWriter.writeLog("Exception: " + e.getMessage());
            }
        }
        
        //need in JavaFX to avoid illegalThreadState
        if(worker!=null && worker.getState()==Thread.State.TERMINATED){
            worker=null;
        }
        
        // restart if not display.running - uses pages to control loop so I hope will
        // pick up change
        if(worker!=null && worker.getState()!=Thread.State.NEW){
            //still running
            //System.out.println(worker.getState()+" "+worker);
        }else if ((worker == null || !multiDisplayOptions.isRunning())) {

            multiDisplayOptions.setRunning(true);
            
            worker = new Thread() {
                @Override
                public void run(){

                    try {

                        if(debugLayout) {
                            System.out.println("START=========================Started decoding pages "
                                    + multiDisplayOptions.getStartViewPage() + ' ' + multiDisplayOptions.getEndViewPage());
                        }

                        decodeOtherPages();

                        if(debugLayout) {
                            System.out.println("END=========================Pages done");
                        }

                        multiDisplayOptions.setRunning(false);

                        //tell user object if exists that pages painted
                        if(customRenderChangeListener!=null) {
                            customRenderChangeListener.renderingWorkerFinished();
                        }

                    } catch (final Exception e) {
                        
                        multiDisplayOptions.setRunning(false);
                        
                        LogWriter.writeLog("Exception: " + e.getMessage());
                    }catch(final Error err){
                        multiDisplayOptions.setRunning(false);
                        
                        LogWriter.writeLog("Error: " + err.getMessage());
                    }finally{
                        semaphore.release();
                    }
                }
            };
            worker.setDaemon(true);
            
            worker.start();
        }
    }

    /**
     * scans all pages in visible range and decodes
     */
    void decodeOtherPages() {

        final int pageCount=pageData.getPageCount();
        if(debugLayout) {
            System.out.println("decodeOtherPages called");
        }

        multiDisplayOptions.setIsGeneratingOtherPages(true);

        int page = multiDisplayOptions.getStartViewPage(), originalStart = multiDisplayOptions.getStartViewPage(), originalEnd = multiDisplayOptions.getEndViewPage()+1;

        //increase decoded range for facing with turnover
        int firstFacing=1, lastFacing=1;
        if (multiDisplayOptions.isTurnoverOn() && displayView == FACING) {
            firstFacing = originalStart - 2;
            lastFacing = firstFacing + 6;

            if (firstFacing < 1) {
                firstFacing = 1;
            }
            if (lastFacing > pageCount+1) {
                lastFacing = pageCount + 1;
            }
        }
        int facingCount = lastFacing-firstFacing;

        resetPageCaches(multiDisplayOptions.getStartViewPage(), multiDisplayOptions.getEndViewPage()+1);

        if(debugLayout){
            System.out.println("decoding ------START " + originalStart + " END="+ originalEnd+" display.isGeneratingOtherPages="+multiDisplayOptions.isIsGeneratingOtherPages());
            System.out.println(multiDisplayOptions.getStartViewPage() + " "+ multiDisplayOptions.getEndViewPage());
        }
        while (multiDisplayOptions.isIsGeneratingOtherPages()) {

            // detect if restarted
            if ((originalStart != multiDisplayOptions.getStartViewPage())&& (originalEnd != multiDisplayOptions.getEndViewPage())) {
                if(debugLayout) {
                    System.out.println("Worker detected change to page range to " + multiDisplayOptions.getStartViewPage() + ' ' + multiDisplayOptions.getEndViewPage());
                }
                
                page = multiDisplayOptions.getStartViewPage();
                originalEnd = multiDisplayOptions.getEndViewPage()+1;

                // can be zero in facing mode
                if (page == 0) {
                    page++;
                }
                originalStart = page;


                if (multiDisplayOptions.isTurnoverOn() && displayView == FACING) {
                    firstFacing = originalStart - 2;
                    lastFacing = firstFacing + 6;

                    if (firstFacing < 1) {
                        firstFacing = 1;
                    }
                    if (lastFacing > pageCount+1) {
                        lastFacing = pageCount + 1;
                    }

                    facingCount = lastFacing-firstFacing;
                }

                resetPageCaches(originalStart, originalEnd);

            }

            // exit if finished
            if (multiDisplayOptions.isTurnoverOn() && displayView == FACING && facingCount==0) {
                break;
            }

            if ((!multiDisplayOptions.isTurnoverOn() || displayView != FACING) && page == originalEnd) {
                break;
            }

            if(originalStart>originalEnd) {
                break;
            }
            
            if (page > 0 && page < pdf.getPageCount()+1) {
                decodeMorePages(page, originalStart, originalEnd);
            }
            
            //store thumbnail for turnover if in facing mode
            if (displayView==FACING && multiDisplayOptions.isTurnoverOn()) {
                int leftPage = multiDisplayOptions.getPageNumber();
                if (multiDisplayOptions.isSeparateCover() && (leftPage & 1) == 1) {
                    leftPage--;
                }
                if (!multiDisplayOptions.isSeparateCover() && (leftPage & 1) == 0) {
                    leftPage--;
                }
                int ref = page-leftPage + 2;
                if (!(ref > 1 && ref < 4 )){

                    if (ref > 1) {
                        ref -= 2;
                    }
                    
                    int[] pageW=multiDisplayOptions.getPageW();
                    int[] pageH=multiDisplayOptions.getPageH();
//                    System.out.println("page + \" \" + ref = " + page + " " + ref);
                    if(ref < 4 && ref > -1 && facingDragCachedImages[ref]==null) {

                        final BufferedImage image = new BufferedImage(pageW[page], pageH[page], BufferedImage.TYPE_INT_ARGB);
                        final Graphics2D pg = (Graphics2D) image.getGraphics();
                        
                        final int displayRotation=display.getDisplayRotation();
                        
                        pg.rotate(displayRotation*Math.PI/180);
                        try {
                            if (displayRotation == 90) {
                                pg.translate(0,-pageW[page]);
                                pg.drawImage(pdf.getPageAsImage(page),0,0,pageH[page]+1,pageW[page]+1,null);
                            } else if (displayRotation == 180) {
                                pg.translate(-pageW[page],-pageH[page]);
                                pg.drawImage(pdf.getPageAsImage(page),0,0,pageW[page]+1, pageH[page]+1, null);
                            } else if (displayRotation == 270) {
                                pg.translate(-pageH[page], 0);
                                pg.drawImage(pdf.getPageAsImage(page),0,0,pageH[page]+1, pageW[page]+1,null);
                            } else {
                                pg.drawImage(pdf.getPageAsImage(page),0,0,pageW[page]+1, pageH[page]+1,null);
                            }
                        } catch(final Exception e) {
                            LogWriter.writeLog("Exception: " + e.getMessage());
                        }

                        facingDragCachedImages[ref] = image;
                    }
                }
            }

            facingCount--;

            //change decode order if facing
            page++;
            if (multiDisplayOptions.isTurnoverOn() && displayView == FACING && page == lastFacing) {
                page = firstFacing;
            }
        }

        if(debugLayout) {
            System.out.println("decodeOtherPageinins------ENDED");
        }
    }

    public void decodeMorePages(int page, int originalStart, int originalEnd) {
        /**
         * decode or get cached page data. If it is still in cache we just need a repaint
         */    
        if(currentPageViews.get(page)==null){

            decodePage(page, originalStart, originalEnd);
        }

        repaint();
        
    }
    
    public void decodePage(int page,int originalStart, int originalEnd) {
        
        final AcroRenderer formRenderer =pdf.getFormRenderer();
        //Create form objects
        if (displayView == CONTINUOUS || displayView == CONTINUOUS_FACING){
            final PdfStreamDecoder current= (PdfStreamDecoder) currentPageViews.get(page);
            
            //if(currentOffset!=null)
            //     formRenderer.getCompData().setPageValues(pdf.getScaling(), displayRotation,(int)getIndent(),0,0,pdf.getDisplayView(),currentOffset.widestPageNR,currentOffset.widestPageR);
            
            formRenderer.createDisplayComponentsForPage(page,current);
            
            
            if(pdf.getSpecialMode()!= SpecialOptions.NONE &&
                    pdf.getSpecialMode()!= SpecialOptions.SINGLE_PAGE &&
                    page!=pdf.getPageCount()) {
              
                formRenderer.createDisplayComponentsForPage(page + 1, current);
            }
            
            
        }
        /** get pdf object id for page to decode */
        final String currentPageOffset = pdf.getIO().getReferenceforPage(page);
        if (debugLayout) {
            System.out.println("Decoding page " + page + " currentPageOffset=" + currentPageOffset + " range=" + originalStart + ' ' + originalEnd);
        }
        /**
         * decode the file if not already decoded and stored
         */
        if (currentPageOffset != null || (formRenderer.isXFA() && formRenderer.useXFA())) {
            final Integer key= page;
            final Object currentView = currentPageViews.get(key);
            if (currentView == null  && multiDisplayOptions.isIsGeneratingOtherPages()) {
                if (debugLayout) {
                    System.out.println("recreate page");
                }
                // force redraw
                display.forceRedraw();
                getPageView(currentPageOffset, page);
            }
        }
    }
    
    
    private void getPageView(final String currentPageOffset, final int pageNumber) {

        final PdfObject pdfObject=new PageObject(currentPageOffset);

        //ensure set (needed for XFA)
        pdfObject.setPageNumber(pageNumber);

        /** read page or next pages */
        currentPdfFile.readObject(pdfObject);

        final PdfObject Resources=pdfObject.getDictionary(PdfDictionary.Resources);

        final DynamicVectorRenderer currentDisplay = getNewDisplay(pageNumber);
            
        /** set hires mode or not for display */
        currentDisplay.setHiResImageForDisplayMode(pdf.isHiResScreenDisplay());

        int val=0;
        
        if(pdf.getDisplayView()==Display.CONTINUOUS && pdf.getDisplayView()==Display.CONTINUOUS_FACING) {
            val = 1;
        }
        
        final PdfStreamDecoder current=formRenderer.getStreamDecoder(currentPdfFile, pdf.isHiResScreenDisplay(), fileAccess.getRes().getPdfLayerList(),true);

        /**
         * draw acroform data onto Panel
         */
        if (formRenderer != null && pdf.isForm()) {
            //  formRenderer.getCompData().setPageValues(scaling, displayRotation,0,0,0,pdf.getDisplayView(),currentOffset.widestPageNR,currentOffset.widestPageR);
            formRenderer.createDisplayComponentsForPage(pageNumber,current);
        }

        current.setParameters(true, true, 7, val, false,pdf.getExternalHandler().getMode().equals(GUIModes.JAVAFX));
        current.setXMLExtraction(pdf.isXMLExtraction());
        pdf.getExternalHandler().addHandlers(current);

        current.setObjectValue(ValueTypes.Name, fileAccess.getFilename());
        current.setObjectValue(ValueTypes.ObjectStore, pdf.getObjectStore());
        current.setObjectValue(ValueTypes.PDFPageData,pageData);
        current.setIntValue(ValueTypes.PageNum, pageNumber);
        current.setRenderer(currentDisplay);

        try {

            currentDisplay.init(pageData.getMediaBoxWidth(pageNumber), pageData.getMediaBoxHeight(pageNumber),options.getPageColor());

            currentDisplay.setValue(DynamicVectorRenderer.ALT_BACKGROUND_COLOR, options.getPageColor().getRGB());
            if(options.getTextColor()!=null){
                currentDisplay.setValue(DynamicVectorRenderer.ALT_FOREGROUND_COLOR, options.getTextColor().getRGB());
                if(options.getChangeTextAndLine()) {
                    currentDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 1);
                } else {
                    currentDisplay.setValue(DynamicVectorRenderer.FOREGROUND_INCLUDE_LINEART, 0);
                }


            }
            fileAccess.getRes().setupResources(current, false, Resources,pageNumber,currentPdfFile);

            current.decodePageContent(pdfObject);

            final TextLines textLines = pdf.getTextLines();
            //All data loaded so now get all line areas for page
            if(textLines!=null){
                final Vector_Rectangle_Int vr = (Vector_Rectangle_Int) current.getObjectValue(ValueTypes.TextAreas);
                vr.trim();
                final int[][] pageTextAreas = vr.get();

                final Vector_Int vi =  (Vector_Int) current.getObjectValue(ValueTypes.TextDirections);
                vi.trim();
                final int[] pageTextDirections = vi.get();

                for(int k=0; k!=pageTextAreas.length; k++){
                    textLines.addToLineAreas(pageTextAreas[k], pageTextDirections[k], pageNumber);
                }
            }

            //tell viewer we have finished so it will generate highlights
            currentDisplay.flagDecodingFinished();

        } catch (final Exception ex) {
            LogWriter.writeLog("Exception: " + ex.getMessage());
        } catch (final Error err) {
            LogWriter.writeLog("Exception: " + err.getMessage());
        }

        currentPageViews.put(pageNumber,currentDisplay);
        
        display.setCurrentDisplay(currentDisplay);
        
    }

    /**
     * copy pages between WeakMap and vice-versa
     */
    void resetPageCaches(final int startPage, final int endPage) {

        // copy any pages in existence into hashMap so not garbage collected
        //synchronized (cachedPageViews) {
        for (final Object o : this.cachedPageViews.keySet()) {
            final Integer currentKey = (Integer) o;
            final int keyValue = currentKey;
            if ((keyValue >= startPage) && (keyValue <= endPage)) {
                final Object obj = cachedPageViews.get(currentKey);
                if (obj != null) {
                    this.currentPageViews.put(currentKey, obj);
                }
            }
        }
        //}

        // move any pages not visible into cache
        {
            //synchronized (currentPageViews) {
            Iterator keys = this.currentPageViews.keySet().iterator();

            final Map keysToTrash = new HashMap();

            while (keys.hasNext()) {
                final Integer currentKey = (Integer) keys.next();
                final int keyValue = currentKey;
                if ((keyValue < startPage) || (keyValue > endPage)) {
                    final Object obj = currentPageViews.get(currentKey);
                    if (obj != null) {
                        this.cachedPageViews.put(currentKey, obj);
                    }

                    // track so we can delete outside loop
                    keysToTrash.put(currentKey, "x");

                }
            }

            // now remove
            keys = keysToTrash.keySet().iterator();

            while (keys.hasNext()) {
                currentPageViews.remove(keys.next());
            }

            //}
        }

        //System.out.println("cache contains " + currentPageViews.keySet());
    }


    /**
     * workout which pages are displayed
     */
    private synchronized void calcDisplayedRange() {

        final int pageCount=pageData.getPageCount();

        if(debugLayout) {
            System.out.println("calcDisplayedRange pageNumber=" + multiDisplayOptions.getPageNumber() + " mode=" + displayView);
        }

        if(displayView==SINGLE_PAGE) {
            return;
        }

        display.getDisplayedRectangle();

        if(displayView==FACING){

          multiDisplayOptions.calcDisplayRangeForFacing();
        
        }else{


            //// START SI'S PAGE COUNTER ////////////

            final int newPage = updatePageDisplayed();
//System.out.println("newPage="+newPage);
            fileAccess.setPageNumber(newPage);

            //// END SI'S PAGE COUNTER ////////////

            //update page number
            if(newPage!=-1)// && customSwingHandle!=null)
            {
                gui.setPage(newPage);//( (org.jpedal.gui.GUIFactory) customSwingHandle).setPage(newPage);
            }
        }

        //Ensure end page is not set beyond the total count of pages
        if(multiDisplayOptions.getEndViewPage()>pageCount) {
            multiDisplayOptions.setEndViewPage(pageCount); 
        }

        if(displayView!=FACING) {
            display.refreshDisplay();      //refresh display to fix backbuffer background color issue
        }
    }

    public void flushPageCaches() {
        currentPageViews.clear();
          
        cachedPageViews.clear();
        
    }

    public DynamicVectorRenderer getCurrentPageView(int i) {
        return (DynamicVectorRenderer) currentPageViews.get(i);
    }

    public void dispose() {
        this.cachedPageViews=null;
    }

    private int updatePageDisplayed() {
        
        int newPage=-1;
        final int pageCount=pageData.getPageCount();

        final int[] yReached=multiDisplayOptions.getyReached();
        
        final int[] pageH = multiDisplayOptions.getPageH();
        final int ry=display.getRy();
        final int rh=display.getRh();
        //final int insetH=display.getInsetH();
        
        final boolean debug=false;
        int largestH = 0;
        int firstVisiblePage = 0;
        int lastVisiblePage = 0;
        for (int i = 1; i <= pageCount; i += 1) {
            
            int pageTop=yReached[i];
            int pageBottom=yReached[i]+pageH[i];
            int viewBottom=ry+rh;
            if(debug){
                System.out.println(display.getInsetH()+" "+i+ ' ' +" pageTop="+pageTop+" pageBottom="+pageBottom+" viewTop="+ ry +" viewBottom="+ viewBottom);
            }
            if( pageTop<=viewBottom && pageBottom>= ry){
                //in view
                
                if(debug){
                    System.out.println("in view ");
                }
            }else{
                
                continue;
            }
            
            //If not set yet, set to first page by default
            if (newPage == -1) {
                newPage = i;
                firstVisiblePage=i;
            }
            lastVisiblePage = i;
            
            int midPt=ry+(rh/2);
            int gap=midPt-yReached[i];
            if(debug){
                System.out.println("gap="+gap);
            }
            if (gap<0 || gap>pageH[i]){
                gap=0;
            }
            
            int gap2=yReached[i]+pageH[i]-midPt;
            if(debug){
                System.out.println("gap2="+gap2);
            }
            if (gap2<0 || gap2>pageH[i]){
                gap2=0;
            }
            
            if(gap2>gap){
                gap=gap2;
            }
            
            if (gap>0 && gap > largestH) {
                largestH =gap;
                newPage = i;
                
                if(debug){
                    System.out.println(i+" gap now="+largestH);
                }
                
                //break; //Stop if found first whole page
            }
            
            if(debug){
                System.out.println(i+" reached "+yReached[i]+ ' ' +ry);
            }
        }
        
        //If still not set set page 1 as a default
        if (newPage == -1) {
            newPage = 1;
            firstVisiblePage = 1;
            lastVisiblePage = 1;
        }
        
        multiDisplayOptions.setStartViewPage(firstVisiblePage);
        //allow for  2 page doc with both pages onscreen
        multiDisplayOptions.setEndViewPage(lastVisiblePage);
        
        if (debugLayout) {
            System.out.println("page range start=" + multiDisplayOptions.getStartViewPage() + " end=" + multiDisplayOptions.getEndViewPage());
        }
        
        //Ensure end page is not set beyond the total count of pages
        if (multiDisplayOptions.getEndViewPage() > pageCount) {
            multiDisplayOptions.setEndViewPage(pageCount);
        }
        
        return newPage;
    }
    
    public void resetCachedFacingImages() {
        for (int i=0; i<4; i++) {
            facingDragCachedImages[i] = null;
        }       
    }

    public BufferedImage[] getFacingDragImages() {
        return facingDragCachedImages;
    }

    public BufferedImage getfacingDragTempLeftImg() {
        return facingDragTempLeftImg;
    }

    public BufferedImage getfacingDragTempRightImg() {
        return facingDragTempRightImg;
    }

    public int getFacingDragTempLeftNo() {
        return facingDragTempLeftNo;
    }
    
    public int getFacingDragTempRightNo() {
        return facingDragTempRightNo;
    }

    public void setCustomRenderChangeListener(RenderChangeListener customRenderChangeListener) {
        this.customRenderChangeListener=customRenderChangeListener;
    }

    public void repaint() {
        throw new UnsupportedOperationException("repaint Not supported yet.");
    }

    public DynamicVectorRenderer getNewDisplay(int pageNumber) {
        throw new UnsupportedOperationException(this+ "Not supported yet."); 
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy